{
  "name": "f1_bot_zoom",
  "nodes": [
    {
      "parameters": {
        "errorMessage": "={{ $json.error.cause.message }}"
      },
      "id": "9774e8ba-a253-483c-9418-d426235e2ea7",
      "name": "No Recording/Transcript available",
      "type": "n8n-nodes-base.stopAndError",
      "position": [
        -20,
        180
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "ef149af8-7f9d-4e5a-8ccf-4a5f1e09eecc",
              "name": "transcript_file",
              "type": "string",
              "value": "={{ $json.recording_files.find(f => f.file_type === 'CC' && f.file_extension === 'VTT')?.download_url }}"
            }
          ]
        },
        "options": {}
      },
      "id": "733d944f-fb3b-4218-ac98-48f75c7bc55c",
      "name": "Filter transcript URL",
      "type": "n8n-nodes-base.set",
      "position": [
        -20,
        0
      ],
      "typeVersion": 3.4,
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "url": "={{ $json.transcript_file }}",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "zoomOAuth2Api",
        "options": {}
      },
      "id": "4c1d9372-2c37-44cb-b8fa-4f40a5b2ebd2",
      "name": "Zoom: Get transcript file",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        160,
        0
      ],
      "typeVersion": 4.2,
      "credentials": {
        "zoomOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "text",
        "options": {}
      },
      "id": "7171bd99-584b-492e-b827-b29366d07f74",
      "name": "Extract text from transcript file",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        340,
        0
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "70019192-02ef-4b0a-a747-3ca5f46aeeaa",
              "name": "transcript",
              "type": "string",
              "value": "={{ $json.data.split('\\r\\n\\r\\n').slice(1).map(block => {\n    const lines = block.split('\\r\\n');\n    return lines.slice(2).join(' ');\n}).join('\\n') }}"
            }
          ]
        },
        "options": {}
      },
      "id": "2861c0dd-37b4-441c-80f0-1936d05749e3",
      "name": "Format transcript text",
      "type": "n8n-nodes-base.set",
      "position": [
        500,
        0
      ],
      "typeVersion": 3.4
    },
    {
      "parameters": {
        "url": "=https://api.zoom.us/v2/past_meetings/{{ $('basic-info-depuration-I').item.json.meetingId }}/participants",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "zoomOAuth2Api",
        "options": {}
      },
      "id": "4f6d7099-0db4-4a60-a953-c6e30bbb3277",
      "name": "Zoom: Get participants data",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        680,
        0
      ],
      "typeVersion": 4.2,
      "credentials": {
        "zoomOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "cc51b7e4-d5c2-4cd4-9488-4d181eaaa02e",
              "name": "subject",
              "type": "string",
              "value": "=\ud83d\udce2 Resumen de la Clase: \"{{ $('Zoom: Get data by meetingId').item.json.topic }}\" - {{ DateTime.fromISO($('Zoom: Get data by meetingId').item.json.start_time).toFormat('yyyy-MM-dd HH:mm') }}"
            },
            {
              "id": "f3940ea2-9084-4c25-828e-5ddaa428ec83",
              "name": "=to",
              "type": "string",
              "value": "=hola@uai.edu.pe, mariana.campos@autonomadeica.edu.pe, dany.mejia@autonomadeica.edu.pe, humberto.quispe@autonomadeica.edu.pe, yassir.bonifacio@autonomadeica.edu.pe, susana.atuncar@autonomadeica.edu.pe, angemar@autonomadeica.edu.pe, karina.garcia@autonomadeica.edu.pe"
            },
            {
              "id": "1211af5b-2240-44ce-9df7-63d93f57806e",
              "name": "body",
              "type": "string",
              "value": "={{ $json.output }}"
            }
          ]
        },
        "options": {}
      },
      "id": "f7403416-13c6-40dd-84e9-877f77c607e0",
      "name": "Sort for mail delivery",
      "type": "n8n-nodes-base.set",
      "position": [
        1280,
        20
      ],
      "typeVersion": 3.4
    },
    {
      "parameters": {
        "jsCode": "const items = [];\nfor (const item of $input.all()) {\n  const body = item.json.body;\n  if (!body) continue;\n  \n  const formatMarkdown = (text) => {\n    return text\n      .replace(/\\*\\*(.*?)\\*\\*/g, '<strong>$1</strong>') // Negrita\n      .replace(/\\n/g, '<br>'); // Saltos de l\u00ednea\n  };\n  \n  const getSection = (sectionTitle) => {\n    const regex = new RegExp(`###\\\\s*${sectionTitle}\\\\s*\\\\n([\\\\s\\\\S]*?)(?=\\\\n###|\\\\n---|$)`, 'i');\n    const match = body.match(regex);\n    return match ? match[1].trim() : '';\n  };\n  \n  const titleMatch = body.match(/\\*\\*\ud83d\udcc5 Fecha:\\*\\*\\s*(.*?)\\s\\s/);\n  const title = titleMatch ? titleMatch[1].trim() : \"Acta de Reuni\u00f3n\";\n  \n  const resumen = getSection(\"\ud83d\udcda Resumen general de la clase\");\n  const observacion = getSection(\"\ud83d\udd0e Observaci\u00f3n sobre la presencia y participaci\u00f3n del docente\");\n  const citas = getSection(\"\ud83d\udcac Intervenciones destacadas o citas relevantes\");\n  const conclusion = getSection(\"\ud83c\udf1f Sugerencias para la mejora docente\");\n  \n  const citasFormateadas = citas\n    .split(\"\\n\")\n    .filter(line => line.trim() !== \"\")\n    .map(line => `<p style=\"margin: 8px 0; color: #2c3e50; font-style: italic; position: relative; padding-left: 20px;\">\"${line.trim()}\"</p>`)\n    .join(\"\\n\");\n  \n  const conclusionFormateada = formatMarkdown(\n    conclusion.replace(/^> /gm, '').trim()\n  );\n  \n  const html = `\n<!DOCTYPE html>\n<html lang=\"es\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Acta de Reuni\u00f3n - ${title}</title>\n    <style>\n        * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\n        }\n        \n        body {\n            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n            min-height: 100vh;\n            padding: 20px;\n            color: #333;\n        }\n        \n        .container {\n            max-width: 800px;\n            margin: 0 auto;\n            background: white;\n            border-radius: 20px;\n            box-shadow: 0 20px 40px rgba(0,0,0,0.1);\n            overflow: hidden;\n            animation: slideIn 0.8s ease-out;\n        }\n        \n        @keyframes slideIn {\n            from { opacity: 0; transform: translateY(30px); }\n            to { opacity: 1; transform: translateY(0); }\n        }\n        \n        .header {\n            background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);\n            padding: 30px;\n            text-align: center;\n            color: white;\n            position: relative;\n            overflow: hidden;\n        }\n        \n        .header::before {\n            content: '';\n            position: absolute;\n            top: -50%;\n            left: -50%;\n            width: 200%;\n            height: 200%;\n            background: radial-gradient(circle, rgba(255,255,255,0.1) 1px, transparent 1px);\n            background-size: 20px 20px;\n            animation: float 20s linear infinite;\n        }\n        \n        @keyframes float {\n            0% { transform: rotate(0deg) translateX(0px); }\n            100% { transform: rotate(360deg) translateX(10px); }\n        }\n        \n        .logo {\n            position: relative;\n            z-index: 2;\n            margin-bottom: 20px;\n        }\n        \n        .logo img {\n            width: 80px;\n            height: 80px;\n            width: auto;\n            height: auto;\n            border-radius: 10px;\n            box-shadow: 0 4px 15px rgba(0,0,0,0.2);\n            background: white;\n            padding: 5px;\n            animation: logoGlow 2s ease-in-out infinite alternate;\n        }\n        \n        @keyframes logoGlow {\n            from { box-shadow: 0 4px 15px rgba(0,0,0,0.2); }\n            to { box-shadow: 0 4px 20px rgba(255,255,255,0.3); }\n        }\n        \n        .header h1 {\n            font-size: 28px;\n            margin-bottom: 10px;\n            position: relative;\n            z-index: 1;\n        }\n        \n        .header .date {\n            font-size: 18px;\n            opacity: 0.9;\n            position: relative;\n            z-index: 1;\n        }\n        \n        .content {\n            padding: 40px;\n        }\n        \n        .section {\n            margin-bottom: 35px;\n            animation: fadeIn 0.6s ease-out;\n        }\n        \n        @keyframes fadeIn {\n            from { opacity: 0; transform: translateY(20px); }\n            to { opacity: 1; transform: translateY(0); }\n        }\n        \n        .section-title {\n            font-size: 22px;\n            color: #2c3e50;\n            margin-bottom: 20px;\n            padding-bottom: 10px;\n            border-bottom: 3px solid #3498db;\n            display: flex;\n            align-items: center;\n            gap: 10px;\n        }\n        \n        .section-content {\n            background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);\n            padding: 25px;\n            border-radius: 15px;\n            border-left: 5px solid #3498db;\n            line-height: 1.8;\n            font-size: 16px;\n            color: #2c3e50;\n            position: relative;\n            overflow: hidden;\n        }\n        \n        .section-content::before {\n            content: '';\n            position: absolute;\n            top: 0;\n            left: -100%;\n            width: 100%;\n            height: 100%;\n            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);\n            animation: shine 3s infinite;\n        }\n        \n        @keyframes shine {\n            0% { left: -100%; }\n            100% { left: 100%; }\n        }\n        \n        .citas-section {\n            background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);\n            color: #2c3e50;\n            padding: 25px;\n            border-radius: 15px;\n            border-left: 5px solid #9b59b6;\n            position: relative;\n            overflow: hidden;\n        }\n        \n        .citas-section::before {\n            content: '';\n            position: absolute;\n            top: 0;\n            left: -100%;\n            width: 100%;\n            height: 100%;\n            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);\n            animation: shine 4s infinite;\n        }\n        \n        .citas-section p {\n            color: #2c3e50 !important;\n            margin: 12px 0;\n            font-size: 16px;\n            position: relative;\n            z-index: 1;\n        }\n        \n        .citas-section p::before {\n            content: '\ud83d\udcac';\n            position: absolute;\n            left: -20px;\n            color: #9b59b6;\n        }\n        \n        .conclusion-section {\n            background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);\n            color: #2c3e50;\n            padding: 25px;\n            border-radius: 15px;\n            border-left: 5px solid #e74c3c;\n            position: relative;\n            overflow: hidden;\n        }\n        \n        .conclusion-section::before {\n            content: '';\n            position: absolute;\n            top: 0;\n            left: -100%;\n            width: 100%;\n            height: 100%;\n            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);\n            animation: shine 5s infinite;\n        }\n        \n        .conclusion-section .section-content {\n            background: transparent;\n            border: none;\n            padding: 0;\n            color: #2c3e50;\n            font-size: 16px;\n            position: relative;\n            z-index: 1;\n        }\n        \n        .footer {\n            background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%);\n            color: white;\n            padding: 25px;\n            text-align: center;\n            font-size: 14px;\n        }\n        \n        .icon {\n            font-size: 24px;\n            margin-right: 8px;\n        }\n        \n        @media (max-width: 600px) {\n            .container {\n                margin: 10px;\n                border-radius: 15px;\n            }\n            \n            .header, .content {\n                padding: 20px;\n            }\n            \n            .header h1 {\n                font-size: 24px;\n            }\n            \n            .section-title {\n                font-size: 20px;\n            }\n            \n            .logo img {\n                max-width: 100px;\n                max-height: 70px;\n            }\n        }\n    </style>\n</head>\n<body>\n    <div class=\"container\">\n        <div class=\"header\">\n            <div class=\"logo\">\n                <img src=\"https://drive.google.com/uc?id=1r2eXR7N8-MyJ0jyqGwosqjI_hXo6OABZ\" alt=\"Logo Tutor.IA\" onerror=\"this.style.display='none'\">\n            </div>\n            <h1>\ud83d\udccb Detalles de la Sesion</h1>\n            <div class=\"date\">\ud83d\udcc5 ${title}</div>\n        </div>\n        \n        <div class=\"content\">\n            ${resumen ? `\n                <div class=\"section\">\n                    <h2 class=\"section-title\">\n                        <span class=\"icon\">\ud83d\udcda</span>\n                        Resumen de la clase\n                    </h2>\n                    <div class=\"section-content\">\n                        ${formatMarkdown(resumen)}\n                    </div>\n                </div>\n            ` : \"\"}\n            \n            ${observacion ? `\n                <div class=\"section\">\n                    <h2 class=\"section-title\">\n                        <span class=\"icon\">\ud83d\udd0e</span>\n                        Observaci\u00f3n sobre la presencia del docente\n                    </h2>\n                    <div class=\"section-content\">\n                        ${formatMarkdown(observacion)}\n                    </div>\n                </div>\n            ` : \"\"}\n            \n            ${citas ? `\n                <div class=\"section\">\n                    <h2 class=\"section-title\">\n                        <span class=\"icon\">\ud83d\udcac</span>\n                        Citas destacadas\n                    </h2>\n                    <div class=\"citas-section\">\n                        ${citasFormateadas}\n                    </div>\n                </div>\n            ` : \"\"}\n            \n            ${conclusion ? `\n                <div class=\"section\">\n                    <h2 class=\"section-title\">\n                        <span class=\"icon\">\ud83c\udf1f</span>\n                        Sugerencias para la mejora docente\n                    </h2>\n                    <div class=\"conclusion-section\">\n                        <div class=\"section-content\">\n                            ${conclusionFormateada}\n                        </div>\n                    </div>\n                </div>\n            ` : \"\"}\n        </div>\n        \n        <div class=\"footer\">\n            <p>\u00a9 2025 Tutor.IA - Acta generada autom\u00e1ticamente</p>\n        </div>\n    </div>\n</body>\n</html>`;\n\n  items.push({\n    json: {\n      html,\n      to: item.json.to,\n      subject: item.json.subject,\n    },\n  });\n}\n\nreturn items;"
      },
      "id": "b2461809-3b0d-4bad-b030-e01c6110f600",
      "name": "Format to html",
      "type": "n8n-nodes-base.code",
      "position": [
        1560,
        0
      ],
      "typeVersion": 2
    },
    {
      "parameters": {
        "fromEmail": "tutor.ia@uai.edu.pe",
        "toEmail": "={{ $json.to }}",
        "subject": "={{ $json.subject }}",
        "html": "={{ $json.html }}",
        "options": {}
      },
      "id": "86c03aa4-b797-469a-8c7a-56504c0cf0ff",
      "name": "Send meeting summary",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        1760,
        0
      ],
      "typeVersion": 2.1,
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "method": "=GET",
        "url": "=https://api.zoom.us/v2/meetings/{{ $json.id }}/recordings",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "zoomOAuth2Api",
        "options": {}
      },
      "id": "079c3aa5-cb81-4172-8ab1-f23dd76c2ef5",
      "name": "Zoom: Get transcripts data",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -220,
        20
      ],
      "typeVersion": 4.2,
      "credentials": {
        "zoomOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=Act\u00faa como un supervisor acad\u00e9mico que eval\u00faa de forma objetiva, clara y constructiva la calidad de una clase grabada en Zoom. Tu tarea es redactar un acta formal que resuma el desarrollo de la sesi\u00f3n, identifique puntos de mejora realistas y valore las oportunidades de crecimiento docente. Mant\u00e9n un tono profesional, imparcial y emp\u00e1tico: no sanciones, orienta.\n\nUtiliza los siguientes datos:\n\n- **Fecha programada de la clase:** {{ $('basic-info-depuration-II').item.json.startTimeLocal }}  \n- **Hora en la que el host inici\u00f3 la reuni\u00f3n:** {{ $('basic-info-depuration-I').item.json.startTimeLocal }}  \n- **Docente (host):** {{ $('Zoom: Get transcripts data').item.json.host_email }}\n\n---\n\n**Transcript crudo con tiempo** (\u00fatil para an\u00e1lisis de presencia y participaci\u00f3n):  \n{{ $('Extract text from transcript file').item.json.data }}\n\n**Transcript limpio** (\u00fatil para redacci\u00f3n del acta):  \n{{ $('Format transcript text').item.json.transcript }}\n\n---\n\nRedacta el acta con la siguiente estructura:\n\n---\n\n### \ud83d\udcdd Acta de Reuni\u00f3n\n\n**\ud83d\udcc5 Fecha:** [En formato DD/MM/AAAA]  \n**\ud83d\udd50 Hora programada:** [Hora programada de la clase]  \n**\ud83d\udd50 Hora real de inicio del host:** [Hora registrada de inicio de la reuni\u00f3n]  \n\n---\n\n### \ud83d\udcda Resumen general de la clase  \nRedacta un p\u00e1rrafo **breve** que describa el enfoque tem\u00e1tico (si lo hay), nivel de preparaci\u00f3n, claridad de objetivos, estructura y participaci\u00f3n. Menciona aspectos positivos o destacables, pero tambi\u00e9n debilidades o \u00e1reas de mejora, usando **negrita** para resaltar hallazgos clave. Mant\u00e9n un tono constructivo y profesional.\n\n---\n\n### \ud83d\udd0e Observaci\u00f3n sobre la presencia y participaci\u00f3n del docente  \n1. Especifica si el docente inici\u00f3 la reuni\u00f3n antes, a tiempo o despu\u00e9s de la hora programada.  \n2. Indica el **momento exacto en el transcript** (en segundos o formato `00:MM:SS`) en el que el docente habl\u00f3 por primera vez.  \n3. Eval\u00faa si hubo **dilataci\u00f3n excesiva entre intervenciones** (por ejemplo, si hay m\u00e1s de 20 minutos sin participaci\u00f3n del docente). Si ocurre, dest\u00e1calo como una se\u00f1al de posible desconexi\u00f3n o falta de conducci\u00f3n activa.  \n4. Usa un tono objetivo y orientado a la mejora profesional.\n\n---\n\n### \ud83d\udcac Intervenciones destacadas o citas relevantes  \nSelecciona m\u00e1ximo 6 l\u00edneas directamente copiadas textualmente del transcript crudo con timestamp incluido, sin reformular ni parafrasear.  \nCada l\u00ednea debe mantenerse **id\u00e9ntica** a como aparece en la transcripci\u00f3n, incluyendo comillas, puntuaci\u00f3n, pausas u onomatopeyas.  \nPresenta cada cita como un \u00edtem de lista con vi\u00f1eta tipo guion (`-`), en este formato:\n\n- \"Texto exacto de la intervenci\u00f3n.\" (`00:00:00`)\n\n\u2757 No agregues introducciones, no resumas ni cambies la redacci\u00f3n. Mant\u00e9n el estilo literal.\n\n---\n\n### \ud83c\udf1f Sugerencias para la mejora docente  \nBrinda **solo 2 recomendaciones** puntuales para mejorar el desempe\u00f1o docente, usando emojis y tono motivador.  \nEjemplos:\n\n- \ud83d\udccc Establecer un objetivo claro y compartido al inicio  \n- \ud83e\uddd1\u200d\ud83c\udfeb Asegurar una presencia activa y constante durante la clase  \n- \ud83e\uddf0 Incorporar ejemplos o recursos visuales que refuercen el contenido  \n- \ud83c\udfaf Guiar la participaci\u00f3n de los estudiantes con preguntas relevantes  \n- \ud83d\uddc2\ufe0f Estructurar la sesi\u00f3n en secciones claras: introducci\u00f3n, desarrollo y cierre  \n- \u23f1\ufe0f Controlar mejor el tiempo para mantener el ritmo y cubrir todos los puntos clave\n\nFinaliza con un mensaje positivo:\n\n> \u2728 Cada clase ofrece una oportunidad para mejorar. Con peque\u00f1os ajustes en la preparaci\u00f3n y conducci\u00f3n, esta experiencia puede transformarse en una sesi\u00f3n significativa para los estudiantes. \u00a1Adelante!\n\n---\n\n### \u2705 Instrucciones finales  \n- S\u00e9 profesional, preciso y respetuoso.  \n- Usa **negrita** para resaltar los hallazgos clave.  \n- No inventes datos si no est\u00e1n disponibles.  \n- Evita repetir ideas y mant\u00e9n el informe claro y enfocado.\n",
        "options": {}
      },
      "id": "ad3987fd-42ae-4f2b-837d-7dbc2f36c72c",
      "name": "Create meeting summary",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        860,
        0
      ],
      "typeVersion": 1.9
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "recording-completed",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -980,
        20
      ],
      "id": "4f38263b-231e-4def-84b4-c7ecf83b839e",
      "name": "recording-completed"
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "operation": "get",
        "meetingId": "={{ $json.meetingId }}",
        "additionalFields": {}
      },
      "id": "d40664f1-eaa6-4057-bdfe-d8d596073e78",
      "name": "Zoom: Get data by meetingId",
      "type": "n8n-nodes-base.zoom",
      "position": [
        -600,
        20
      ],
      "typeVersion": 1,
      "alwaysOutputData": false,
      "executeOnce": false,
      "retryOnFail": false,
      "credentials": {
        "zoomOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "typeVersion": 1.2,
      "position": [
        840,
        220
      ],
      "id": "0d845e89-3f7b-4f4d-a479-95b601209810",
      "name": "OpenAI Chat Model",
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const { object } = $json.body.payload;\n\n// Convertir start_time UTC a hora local (Per\u00fa)\nconst startTimeUTC = new Date(object.start_time);\n\nconst options = {\n  timeZone: 'America/Lima',\n  hour12: false,\n  year: 'numeric',\n  month: '2-digit',\n  day: '2-digit',\n  hour: '2-digit',\n  minute: '2-digit',\n};\n\nconst startTimeLocal = startTimeUTC.toLocaleString('es-PE', options); // ejemplo: \"27/06/2025, 10:30\"\n\nreturn {\n  json: {\n    meetingId: object.id,\n    topic: object.topic,\n    startTimeUTC: object.start_time,\n    startTimeLocal: startTimeLocal,\n    uuid: object.uuid,\n    hostId: object.host_id\n  }\n};\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -780,
        20
      ],
      "id": "bde1b6d0-c87e-4c50-bb80-10c5bc7b4c7f",
      "name": "basic-info-depuration-I"
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const data = $json;\n\n// Convertir start_time de UTC a hora local (Per\u00fa)\nconst startTimeUTC = new Date(data.start_time);\nconst options = {\n  timeZone: 'America/Lima',\n  hour12: false,\n  year: 'numeric',\n  month: '2-digit',\n  day: '2-digit',\n  hour: '2-digit',\n  minute: '2-digit',\n};\nconst startTimeLocal = startTimeUTC.toLocaleString('es-PE', options); // Resultado: \"27/06/2025, 10:30\"\n\nreturn {\n  json: {\n    uuid: data.uuid,\n    id: data.id,\n    hostId: data.host_id,\n    hostEmail: data.host_email,\n    assistantId: data.assistant_id,\n    topic: data.topic,\n    type: data.type,\n    status: data.status,\n    startTimeUTC: data.start_time,\n    startTimeLocal: startTimeLocal,\n    duration: data.duration,\n    timezone: data.timezone,\n    agenda: data.agenda,\n    createdAt: data.created_at,\n    startUrl: data.start_url,\n    joinUrl: data.join_url\n  }\n};\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -420,
        20
      ],
      "id": "41b4e133-7387-43f9-8512-eb790b761d07",
      "name": "basic-info-depuration-II"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "meeting-started",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -1000,
        -580
      ],
      "id": "47e49a81-ccce-47b3-b053-4f906af79d6c",
      "name": "meeting-started"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "cc51b7e4-d5c2-4cd4-9488-4d181eaaa02e",
              "name": "subject",
              "type": "string",
              "value": "=\ud83d\udcc4 Formulario de la clase: \"{{ $('meeting-info').item.json.meeting.topic }}\" - {{ $('meeting-info').item.json.meeting.startTime }}"
            },
            {
              "id": "f3940ea2-9084-4c25-828e-5ddaa428ec83",
              "name": "=to",
              "type": "string",
              "value": "={{ $('meeting-info').item.json.meeting.host.email }}"
            },
            {
              "id": "1211af5b-2240-44ce-9df7-63d93f57806e",
              "name": "body",
              "type": "string",
              "value": "=<!DOCTYPE html>\n<html lang=\"es\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>Tutor.IA - Mensaje</title>\n  <style>\n      * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\n        }\n        \n        body {\n            font-family: 'Arial', sans-serif;\n            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n            min-height: 100vh;\n            padding: 20px;\n        }\n        \n        .container {\n            max-width: 600px;\n            margin: 0 auto;\n            background: white;\n            border-radius: 20px;\n            box-shadow: 0 20px 40px rgba(0,0,0,0.1);\n            overflow: hidden;\n            animation: slideIn 0.8s ease-out;\n        }\n        \n        @keyframes slideIn {\n            from {\n                opacity: 0;\n                transform: translateY(30px);\n            }\n            to {\n                opacity: 1;\n                transform: translateY(0);\n            }\n        }\n        \n        .header {\n            background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);\n            padding: 30px;\n            text-align: center;\n            position: relative;\n            overflow: hidden;\n        }\n        \n        .header::before {\n            content: '';\n            position: absolute;\n            top: -50%;\n            left: -50%;\n            width: 200%;\n            height: 200%;\n            background: radial-gradient(circle, rgba(255,255,255,0.1) 1px, transparent 1px);\n            background-size: 20px 20px;\n            animation: float 20s linear infinite;\n        }\n        \n        @keyframes float {\n            0% { transform: rotate(0deg) translateX(0px); }\n            100% { transform: rotate(360deg) translateX(10px); }\n        }\n        \n        .logo {\n            width: 455px;\n            height: 120px;\n            margin: 0 auto 20px;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            position: relative;\n            z-index: 1;\n            animation: pulse 2s infinite;\n            overflow: hidden;\n            border-radius: 15px;\n        }\n        \n        .logo img {\n            width: 100%;\n            height: 100%;\n            object-fit: cover;\n            border-radius: 15px;\n        }\n        \n        @keyframes pulse {\n            0%, 100% { transform: scale(1); }\n            50% { transform: scale(1.05); }\n        }\n        \n        .company-name {\n            color: white;\n            font-size: 28px;\n            font-weight: bold;\n            position: relative;\n            z-index: 1;\n        }\n        \n        .content {\n            padding: 40px;\n        }\n        \n        .greeting {\n            font-size: 24px;\n            color: #2d3748;\n            margin-bottom: 30px;\n            font-weight: 600;\n        }\n        \n        .message {\n            font-size: 16px;\n            line-height: 1.8;\n            color: #4a5568;\n            margin-bottom: 30px;\n        }\n        \n        .link-section {\n            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n            color: white;\n            padding: 25px;\n            border-radius: 15px;\n            margin: 30px 0;\n            text-align: center;\n            position: relative;\n            overflow: hidden;\n        }\n        \n        .link-section::before {\n            content: '';\n            position: absolute;\n            top: 0;\n            left: -100%;\n            width: 100%;\n            height: 100%;\n            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);\n            animation: shine 3s infinite;\n        }\n        \n        @keyframes shine {\n            0% { left: -100%; }\n            100% { left: 100%; }\n        }\n        \n        .link-section h3 {\n            margin-bottom: 15px;\n            position: relative;\n            z-index: 1;\n        }\n        \n        .link-section p {\n            position: relative;\n            z-index: 1;\n        }\n        \n        .link-section a {\n            color: #ffd700;\n            text-decoration: none;\n            font-weight: bold;\n            word-break: break-all;\n        }\n        \n        .link-section a:hover {\n            text-decoration: underline;\n        }\n        \n        .footer {\n            background: linear-gradient(135deg, #2d3748 0%, #4a5568 100%);\n            color: white;\n            padding: 30px;\n            text-align: center;\n        }\n        \n        .contact-info {\n            font-size: 14px;\n            color: rgba(255,255,255,0.8);\n        }\n        \n        @media (max-width: 600px) {\n            .container {\n                margin: 10px;\n                border-radius: 15px;\n            }\n            \n            .header, .content, .footer {\n                padding: 20px;\n            }\n            \n            .logo {\n                width: 290px;\n                height: 100px;\n            }\n            \n            .company-name {\n                font-size: 24px;\n            }\n            \n            .greeting {\n                font-size: 20px;\n            }\n        }\n  </style>\n</head>\n<body>\n  <div class=\"container\">\n    <div class=\"header\">\n      <div class=\"logo\">\n        <img src=\"https://drive.google.com/uc?id=1l22pb0dFRDVHnOs4ijKMQZlXI8hy5peG\" alt=\"Tutor.IA Logo\">\n      </div>\n    </div>\n    <div class=\"content\">\n      <div class=\"greeting\">\u00a1Hola, {{ $('meeting-info').item.json.meeting.host.email }}! \ud83d\ude04</div>\n      <div class=\"message\">Se le comparte el link para que sus alumnos le den feedback a su clase.</div>\n      <div class=\"link-section\">\n        <p><a href=\"{{ $json.formLink }}\" target=\"_blank\">{{ $json.formLink }}</a></p>\n      </div>\n    </div>\n    <div class=\"footer\">\n      <div class=\"contact-info\">\n        <small>\u00a9 2025 Tutor.IA. Todos los derechos reservados.</small>\n      </div>\n    </div>\n  </div>\n</body>"
            },
            {
              "id": "de580983-c982-46c8-94c2-395580b1bee7",
              "name": "",
              "value": "",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "d170faf4-3b11-4d05-92d3-003ab95d977d",
      "name": "Sort for mail",
      "type": "n8n-nodes-base.set",
      "position": [
        -200,
        -580
      ],
      "typeVersion": 3.4
    },
    {
      "parameters": {
        "fromEmail": "tutor.ia@uai.edu.pe",
        "toEmail": "={{ $json.to }}",
        "subject": "={{ $json.subject }}",
        "html": "={{ $json.body }}",
        "options": {}
      },
      "id": "9eeecca8-f22d-4909-aaf8-7d4ffcc740b2",
      "name": "Send url for students",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        0,
        -580
      ],
      "typeVersion": 2.1,
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "operation": "get",
        "meetingId": "={{ $json.body.payload.object.id }}",
        "additionalFields": {}
      },
      "id": "73e7e906-9d57-4d0f-bd0d-f150c918ff9b",
      "name": "Zoom: Get-data-by-meetingId",
      "type": "n8n-nodes-base.zoom",
      "position": [
        -820,
        -580
      ],
      "typeVersion": 1,
      "alwaysOutputData": false,
      "executeOnce": false,
      "retryOnFail": false,
      "credentials": {
        "zoomOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const object = $json;\n\n// Convertir start_time UTC a hora local (Per\u00fa)\nconst startTimeUTC = new Date(object.start_time);\n\nconst options = {\n  timeZone: \"America/Lima\",\n  hour12: false,\n  year: \"numeric\",\n  month: \"2-digit\",\n  day: \"2-digit\",\n  hour: \"2-digit\",\n  minute: \"2-digit\",\n};\n\nconst startTimeLocal = startTimeUTC.toLocaleString(\"es-PE\", options); // ejemplo: \"27/06/2025, 10:30\"\n\nreturn {\n  json: {\n    meeting: {\n      id: object.id,\n      uuid: object.uuid,\n      topic: object.topic,\n      startTime: startTimeLocal,\n      status: object.status,\n      duration: object.duration,\n      host: {\n      id: object.host_id,\n      email: object.host_email,\n    },\n    }\n  },\n};\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -620,
        -580
      ],
      "id": "a3c44fdf-3f9d-4ecd-85f6-07648d9992ca",
      "name": "meeting-info"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "participant-joined",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -980,
        -180
      ],
      "id": "f29afb03-db1f-4301-b5ef-1b18687eb0a3",
      "name": "participants-joined"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://known-moth-included.ngrok-free.app/ms/v1/meeting/save",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"payload\": {\n    \"object\": {\n      \"id\": {{ $json.meeting.id }},\n      \"uuid\": \"{{ $json.meeting.uuid }}\",\n      \"topic\": \"{{ $json.meeting.topic }}\",\n      \"start_time\": \"{{ $json.meeting.startTime }}\",\n      \"join_url\": \"{{ $json.meeting.join_url }}\",\n      \"status\": \"pending\",\n      \"duration\": {{ $json.meeting.duration }},\n      \"host_id\": \"{{ $json.meeting.host.id }}\",\n      \"host_email\": \"{{ $json.meeting.host.email }}\"\n    }\n  }\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -560,
        -800
      ],
      "id": "9cce9439-8e84-44e5-8d52-9c896eb59866",
      "name": "/ms/v1/meeting/save"
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const eventObject = $json.body.payload.object;\nconst participant = eventObject.participant;\n\n// Convertir start_time UTC a hora local (Per\u00fa)\nconst joinTimeUTC = new Date(participant.join_time);\n\nconst options = {\n  timeZone: \"America/Lima\",\n  hour12: false,\n  year: \"numeric\",\n  month: \"2-digit\",\n  day: \"2-digit\",\n  hour: \"2-digit\",\n  minute: \"2-digit\",\n};\n\nconst joinTimeLocal = joinTimeUTC.toLocaleString(\"es-PE\", options);\n\nreturn {\n  json: {\n    meeting: {\n      id: eventObject.id,\n      uuid: eventObject.uuid,\n    },\n    participant: {\n      id: participant.id,\n      user_id: participant.user_id,\n      participant_user_id: participant.participant_user_id || null,\n      user_name: participant.user_name,\n      email: participant.email || null,\n      join_time: joinTimeLocal,\n      isHost: participant.participant_user_id === eventObject.host_id,\n    },\n    host_id: eventObject.host_id,\n  },\n};\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -780,
        -180
      ],
      "id": "527929ac-6634-431c-a7d4-f09047d19e68",
      "name": "participant-info"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://known-moth-included.ngrok-free.app/ms/v1/participant/save",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"payload\": {\n    \"object\": {\n      \"user_id\": \"{{ $json.participant.user_id }}\",\n      \"participant_user_id\": \"{{ $json.participant.participant_user_id }}\",\n      \"user_name\": \"{{ $json.participant.user_name }}\",\n      \"email\": \"{{ $json.participant.email }}\",\n      \"join_time\": \"{{ $json.participant.join_time }}\",\n      \"isHost\": {{ $json.participant.isHost }},\n      \"host_id\": \"{{ $json.host_id }}\",\n      \"meeting_id\": \"{{ $json.meeting.id }}\",\n      \"meeting_uuid\": \"{{ $json.meeting.uuid }}\"\n    }\n  }\n}\n\n",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -560,
        -180
      ],
      "id": "a8209758-1070-4f59-b68e-4bf6607efcba",
      "name": "/ms/v1/participant/save"
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "operation": "getAll",
        "returnAll": true,
        "filters": {}
      },
      "type": "n8n-nodes-base.zoom",
      "typeVersion": 1,
      "position": [
        920,
        980
      ],
      "id": "4fce3783-4f7d-48fb-95cc-cd13766dc297",
      "name": "Get many meetings",
      "credentials": {
        "zoomOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const uniqueMeetingsMap = new Map();\n\nitems\n  .sort((a, b) => new Date(b.json.created_at) - new Date(a.json.created_at))\n  .forEach(item => {\n    const now = new Date();\n    const start = new Date(item.json.start_time);\n    const end = new Date(start.getTime() + item.json.duration * 60000);\n\n    let estado = '';\n    if (now < start) {\n      estado = 'pendiente';\n    } else if (now >= start && now <= end) {\n      estado = 'en curso';\n    } else {\n      estado = 'finalizado';\n    }\n\n    // Solo agrega si a\u00fan no existe una reuni\u00f3n con este ID\n    if (!uniqueMeetingsMap.has(item.json.id)) {\n      uniqueMeetingsMap.set(item.json.id, {\n        json: {\n          ...item.json,\n          estado,\n        }\n      });\n    }\n  });\n\n// Tomar los primeros 15 elementos \u00fanicos\nreturn Array.from(uniqueMeetingsMap.values()).slice(0, 15);\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1140,
        980
      ],
      "id": "6f55cee4-2bdd-4b89-97f2-50726eef417e",
      "name": "add status field"
    },
    {
      "parameters": {
        "path": "/api/reuniones/get-all",
        "responseMode": "responseNode",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        720,
        980
      ],
      "id": "0e658ff2-29a3-4b92-8a75-f9d61b0dc657",
      "name": "api/reuniones",
      "disabled": true
    },
    {
      "parameters": {
        "respondWith": "allIncomingItems",
        "options": {
          "responseCode": 200
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.4,
      "position": [
        1360,
        980
      ],
      "id": "df02834a-99bc-42b0-b6d7-b561b4d6c34b",
      "name": "endpoint"
    },
    {
      "parameters": {
        "jsCode": "const uriBase = \"https://encuesta-e0vth.web.app\"\nconst idMeeting = $input.first().json.meeting.id\nconst idHost = $input.first().json.meeting.host.id\n\nreturn {\n  formLink: `${uriBase}/${idMeeting}/${idHost}`\n}"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -420,
        -580
      ],
      "id": "60cacd45-4125-4116-bd75-0c5c99eaa84e",
      "name": "encuesta - link"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "cc51b7e4-d5c2-4cd4-9488-4d181eaaa02e",
              "name": "subject",
              "type": "string",
              "value": "=\ud83d\udce2 Resumen de la Clase: \"{{ $('Zoom: Get data by meetingId').item.json.topic }}\" - {{ DateTime.fromISO($('Zoom: Get data by meetingId').item.json.start_time).toFormat('yyyy-MM-dd HH:mm') }}"
            },
            {
              "id": "f3940ea2-9084-4c25-828e-5ddaa428ec83",
              "name": "=to",
              "type": "string",
              "value": "=hola@uai.edu.pe"
            },
            {
              "id": "1211af5b-2240-44ce-9df7-63d93f57806e",
              "name": "body",
              "type": "string",
              "value": "={{ $json.output }}"
            }
          ]
        },
        "options": {}
      },
      "id": "b0965436-1479-45e3-bf40-701d300982bf",
      "name": "TEST - Sort for mail delivery",
      "type": "n8n-nodes-base.set",
      "position": [
        1280,
        220
      ],
      "typeVersion": 3.4
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "meeting-created",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -1000,
        -800
      ],
      "id": "18d78d06-8cc3-45b7-967d-f80b52c7ff8e",
      "name": "meeting-created"
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const meeting = $json.body.payload.object;\nconst operatorEmail = $json.body.payload.operator;\n\n// Convertir start_time UTC a hora local (Per\u00fa)\nconst startTimeUTC = new Date(meeting.start_time);\n\nconst options = {\n  timeZone: \"America/Lima\",\n  hour12: false,\n  year: \"numeric\",\n  month: \"2-digit\",\n  day: \"2-digit\",\n  hour: \"2-digit\",\n  minute: \"2-digit\",\n};\n\nconst startTimeLocal = startTimeUTC.toLocaleString(\"es-PE\", options);\n\nreturn {\n  json: {\n    meeting: {\n      id: meeting.id,\n      uuid: meeting.uuid,\n      topic: meeting.topic,\n      startTime: startTimeLocal,\n      join_url: meeting.join_url,\n      status: \"pending\",\n      duration: meeting.duration,\n      host: {\n        id: meeting.host_id,\n        email: operatorEmail || \"\",\n      },\n    },\n  },\n};\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -760,
        -800
      ],
      "id": "1df42446-7f3c-4781-b962-c03fc40077e5",
      "name": "meeting-info1"
    },
    {
      "parameters": {
        "method": "PATCH",
        "url": "=https://known-moth-included.ngrok-free.app/ms/v1/meeting/status/{{ $json.meeting.id }}",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n \"status\": \"started\"\n}\n\n",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -420,
        -400
      ],
      "id": "ecd06f2d-df90-4b59-beb0-ed7e3544c42d",
      "name": "/ms/v1/meeting/status/:meeting_id"
    },
    {
      "parameters": {
        "method": "PATCH",
        "url": "=https://known-moth-included.ngrok-free.app/ms/v1/meeting/summary/{{ $('basic-info-depuration-I').item.json.meetingId }}",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n \"summary\": {{ $json.summary }}\n}\n\n",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1980,
        220
      ],
      "id": "f80e7608-2b29-498d-b85e-41f2d9cd7006",
      "name": "/ms/v1/meeting/summary/:meeting_id"
    },
    {
      "parameters": {
        "jsCode": "const rawHtml = $json.html;\nreturn {\n  summary: JSON.stringify(rawHtml) // convierte a string escapado v\u00e1lido\n};"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1760,
        220
      ],
      "id": "ed481668-4674-4036-9f16-3de69b643efe",
      "name": "format to firebase"
    },
    {
      "parameters": {
        "method": "PATCH",
        "url": "=https://known-moth-included.ngrok-free.app/ms/v1/meeting/status/{{ $json.body.payload.object.id }}",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n \"status\": \"finished\"\n}\n\n",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -780,
        300
      ],
      "id": "0d762604-beb8-4dbe-95e9-7de8f3ff2101",
      "name": "/ms/v1/meeting/status/:meeting_id - finished"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "meeting-end",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -1000,
        300
      ],
      "id": "2d9084d8-dd3c-4e8b-a49b-09c84b8634fa",
      "name": "meeting-end"
    },
    {
      "parameters": {
        "content": "## CASI OBSOLETO\n",
        "height": 260,
        "width": 920
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        660,
        920
      ],
      "id": "0d5a8e52-9043-4653-b7a1-930a89c208b8",
      "name": "Sticky Note"
    }
  ],
  "connections": {
    "Format to html": {
      "main": [
        [
          {
            "node": "Send meeting summary",
            "type": "main",
            "index": 0
          },
          {
            "node": "format to firebase",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter transcript URL": {
      "main": [
        [
          {
            "node": "Zoom: Get transcript file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create meeting summary": {
      "main": [
        [
          {
            "node": "TEST - Sort for mail delivery",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format transcript text": {
      "main": [
        [
          {
            "node": "Zoom: Get participants data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Zoom: Get transcript file": {
      "main": [
        [
          {
            "node": "Extract text from transcript file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Zoom: Get transcripts data": {
      "main": [
        [
          {
            "node": "Filter transcript URL",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No Recording/Transcript available",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Zoom: Get participants data": {
      "main": [
        [
          {
            "node": "Create meeting summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract text from transcript file": {
      "main": [
        [
          {
            "node": "Format transcript text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Zoom: Get data by meetingId": {
      "main": [
        [
          {
            "node": "basic-info-depuration-II",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "recording-completed": {
      "main": [
        [
          {
            "node": "basic-info-depuration-I",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Create meeting summary",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "basic-info-depuration-I": {
      "main": [
        [
          {
            "node": "Zoom: Get data by meetingId",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "basic-info-depuration-II": {
      "main": [
        [
          {
            "node": "Zoom: Get transcripts data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "meeting-started": {
      "main": [
        [
          {
            "node": "Zoom: Get-data-by-meetingId",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sort for mail": {
      "main": [
        [
          {
            "node": "Send url for students",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Zoom: Get-data-by-meetingId": {
      "main": [
        [
          {
            "node": "meeting-info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "meeting-info": {
      "main": [
        [
          {
            "node": "encuesta - link",
            "type": "main",
            "index": 0
          },
          {
            "node": "/ms/v1/meeting/status/:meeting_id",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "participants-joined": {
      "main": [
        [
          {
            "node": "participant-info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "participant-info": {
      "main": [
        [
          {
            "node": "/ms/v1/participant/save",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get many meetings": {
      "main": [
        [
          {
            "node": "add status field",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "add status field": {
      "main": [
        [
          {
            "node": "endpoint",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "api/reuniones": {
      "main": [
        [
          {
            "node": "Get many meetings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "encuesta - link": {
      "main": [
        [
          {
            "node": "Sort for mail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "TEST - Sort for mail delivery": {
      "main": [
        [
          {
            "node": "Format to html",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "meeting-created": {
      "main": [
        [
          {
            "node": "meeting-info1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "meeting-info1": {
      "main": [
        [
          {
            "node": "/ms/v1/meeting/save",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "/ms/v1/meeting/summary/:meeting_id": {
      "main": [
        []
      ]
    },
    "format to firebase": {
      "main": [
        [
          {
            "node": "/ms/v1/meeting/summary/:meeting_id",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "meeting-end": {
      "main": [
        [
          {
            "node": "/ms/v1/meeting/status/:meeting_id - finished",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "3c5f0e01-ee16-4428-8724-a32d80d24d37",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "JA4YirAEmOgYdeDJ",
  "tags": []
}