Preguntas y respuestas mensuales de Recursos Humanos en Google Meet

Avanzado

Este es unHR, AI Summarizationflujo de automatización del dominio deautomatización que contiene 26 nodos.Utiliza principalmente nodos como Set, Form, Merge, MySql, Aggregate. Automatizar reuniones de preguntas y respuestas de RRHH con agrupación de preguntas por IA e integración de Google Calendar

Requisitos previos
  • Información de conexión de la base de datos MySQL
  • Clave de API de OpenAI
Vista previa del flujo de trabajo
Visualización de las conexiones entre nodos, con soporte para zoom y panorámica
Exportar flujo de trabajo
Copie la siguiente configuración JSON en n8n para importar y usar este flujo de trabajo
{
  "id": "1VM3ArDydbQVPrdN",
  "meta": {
    "instanceId": "46f10f8f90bd424d08d7ec9e92bdd735f336873f2ca9f21d76cc7ac132eeaabd",
    "templateCredsSetupCompleted": true
  },
  "name": "Monthly HR Q&A in Google Meet",
  "tags": [],
  "nodes": [
    {
      "id": "fedb0008-1164-4c8c-b699-a4576ccb3f14",
      "name": "Agente de IA",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1536,
        288
      ],
      "parameters": {
        "text": "=Questions:\n\n{{ $json.questions.toJsonString() }}",
        "options": {
          "systemMessage": "=# HR Monthly Q&A Agent\n\nYou are an assistant specialized in organizing Monthly HR Q&A meetings.  \nYou will (1) process employees’ submitted questions, (2) deduplicate and cluster them, (3) prioritize by frequency, (4) create a Google Meet using the tool **Create an event in Google Calendar**, and (5) return a JSON object containing the meeting info and a **script text** (a written guide with all the questions for the HR staff to follow).\n\n---\n\n## Input\nYou will always receive a JSON array of questions in this format:\n\n```json\n[\n  {\n    \"id\": 1,\n    \"name\": \"Gabriel\",\n    \"department\": \"Inovação\",\n    \"email\": \"gabriel.hmedeirossantos@gmail.com\",\n    \"question\": \"Como é o VR? e qual a data de pagamento?\",\n    \"created_at\": \"2025-09-16 13:52:54\"\n  }\n]\n````\n\n---\n\n## Workflow\n\n### 1) Validate\n\n* Keep only entries with a valid `question` and `email`.\n* Deduplicate by **email** (for attendance), but keep all questions.\n\n### 2) Normalize\n\n* Simplify each question into a **short, clear version**.\n* Preserve the original language.\n\n### 3) Cluster & Deduplicate\n\n* Group semantically similar questions.\n* Select a **canonical phrasing** for each cluster.\n\n### 4) Prioritize\n\n* Order clusters by `count` (how many employees asked them).\n* Break ties using earliest `created_at`.\n\n### 5) Schedule Google Meet\n\nMeeting date\n\n## Calendar Tool\n- You have access to the tool **Create an event in Google Calendar**.\n- You MUST call this tool to schedule the meeting (last Friday of the current month, 16:00–17:00, America/Sao_Paulo) before returning the final JSON.\n- The tool must be called with:\n  - `title`: \"Monthly HR Q&A – {Month YYYY}\"\n  - `start`: {{ $json.start_date }}\n  - `end`: {{ $json.end_date }}\n  - `timezone`: \"America/Sao_Paulo\"\n  - `attendees`: array of unique emails\n  - **Conference/Meet enabled**\n- After the tool returns, extract `event_id` and `meet_link` (hangoutLink) from the tool response and use them in the output.\n\n---\n\n## Output\n\nAlways return a JSON with two top-level keys: `meeting` and `script`.\n\n### JSON shape\n\n```json\n{\n  \"meeting\": {\n    \"title\": \"Monthly HR Q&A – September 2025\",\n    \"start\": \"2025-09-26T16:00:00-03:00\",\n    \"end\": \"2025-09-26T17:00:00-03:00\",\n    \"timezone\": \"America/Sao_Paulo\",\n    \"meet_link\": \"https://meet.google.com/xxx-xxxx-xxx\",\n    \"event_id\": \"abcdef123456\",\n    \"attendees_count\": 12\n  },\n  \"script\": \"## Script for HR Q&A – September 2025\\n\\n### 1) Meal voucher and payment date (7 employees)\\nHow does the meal voucher work and what is the payment date?\\n\\n### 2) Health plan coverage for spouse (5 employees)\\nCan I include my spouse in the health plan and what is the cost?\\n\\n### 3) Dental plan discount (3 employees)\\nDoes the company offer a dental plan and what is the discount?\\n\\n---\\nTotal clusters: 3 | Total submissions: 15\"\n}\n```\n\n---\n\n## Notes\n\n* `script` must be a **single text field**, formatted as Markdown, not an array of objects.\n* It should read like a **meeting guide**: ordered list of questions, with counts and canonical phrasing.\n* If no questions are valid, still schedule the meeting and set `script` to: `\"No questions were submitted this month.\"`."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "5f7a1fd8-4935-4447-9a78-ddee0be57542",
      "name": "Crear evento en Google Calendar",
      "type": "n8n-nodes-base.googleCalendarTool",
      "position": [
        1632,
        512
      ],
      "parameters": {
        "end": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('End', ``, 'string') }}",
        "start": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Start', ``, 'string') }}",
        "calendar": {
          "__rl": true,
          "mode": "list",
          "value": "gabriel.hmedeirossantos@gmail.com",
          "cachedResultName": "gabriel.hmedeirossantos@gmail.com"
        },
        "additionalFields": {
          "summary": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Summary', ``, 'string') }}",
          "attendees": [
            "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('attendees0_Attendees', `The attendees of the event. Multiple ones can be separated by comma.`, 'string') }}"
          ],
          "description": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Description', ``, 'string') }}"
        }
      },
      "credentials": {
        "googleCalendarOAuth2Api": {
          "id": "0VoHlbfiHi81dc7p",
          "name": "Google Calendar account"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "c64f155a-bdcc-46c2-a47e-6a14998a0752",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1472,
        512
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "zwivGqRORUgpjepY",
          "name": "OpenAi account"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "8b59e674-859c-462f-b8b2-dea794351f28",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1792,
        512
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"meeting\": {\n    \"title\": \"Monthly HR Q&A – September 2025\",\n    \"start\": \"2025-09-26T16:00:00-03:00\",\n    \"end\": \"2025-09-26T17:00:00-03:00\",\n    \"timezone\": \"America/Sao_Paulo\",\n    \"meet_link\": \"https://meet.google.com/xxx-xxxx-xxx\",\n    \"event_id\": \"abcdef123456\",\n    \"attendees_count\": 12\n  },\n  \"script\": \"## Script for HR Q&A – September 2025\\n\\n### 1) Meal voucher and payment date (7 employees)\\nHow does the meal voucher work and what is the payment date?\\n\\n### 2) Health plan coverage for spouse (5 employees)\\nCan I include my spouse in the health plan and what is the cost?\\n\\n### 3) Dental plan discount (3 employees)\\nDoes the company offer a dental plan and what is the discount?\\n\\n---\\nTotal clusters: 3 | Total submissions: 15\"\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "65d92503-fad1-4816-88d4-9f28a03afa77",
      "name": "Convert to File",
      "type": "n8n-nodes-base.convertToFile",
      "position": [
        2208,
        288
      ],
      "parameters": {
        "options": {
          "fileName": "MeetingItinerary.txt"
        },
        "operation": "toText",
        "sourceProperty": "output.script"
      },
      "typeVersion": 1.1
    },
    {
      "id": "3eb9a6d5-3e1a-4761-aafe-4ec1c7fcf028",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        2592,
        304
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "d0af1ffb-9b14-47d6-b0fa-74828c16398b",
      "name": "Formulario de preguntas",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -208,
        -144
      ],
      "webhookId": "abc351d4-2aca-4228-b86d-49873b150b3e",
      "parameters": {
        "options": {
          "customCss": "/* ===== Base layout ===== */\nhtml, body {\n  height: 100%;\n  font-family: var(--font-family);\n  font-weight: var(--font-weight-normal);\n  font-size: var(--font-size-body);\n  background:\n    radial-gradient(1200px 800px at 10% -10%, #f0f2ff 0%, transparent 60%),\n    radial-gradient(1000px 700px at 110% 0%, #fef3f0 0%, transparent 55%),\n    var(--color-background);\n  color: var(--color-html-text);\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\n.container, .form-wrapper, .n8n-form {\n  max-width: var(--container-width);\n  margin: 32px auto;\n  padding: 0 12px;\n}\n\n/* ===== Test banner (top) ===== */\n.test-notice {\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  margin: 0 auto 12px;\n  max-width: var(--container-width);\n  background: var(--color-test-notice-bg);\n  border: 1px solid var(--color-test-notice-border);\n  color: var(--color-test-notice-text);\n  padding: var(--padding-test-notice-vertical) var(--padding-test-notice-horizontal);\n  border-radius: var(--border-radius-input);\n  font-size: var(--font-size-test-notice);\n}\n\n/* ===== Card ===== */\n.form-card {\n  background: var(--color-card-bg);\n  border: 1px solid var(--color-card-border);\n  border-radius: var(--border-radius-card);\n  box-shadow: var(--box-shadow-card);\n  padding: var(--padding-card);\n  margin-bottom: var(--margin-bottom-card);\n}\n\n/* ===== Headings & subtitle ===== */\n.form-card h1,\nh1.form-title {\n  font-size: var(--font-size-header);\n  color: var(--color-header);\n  margin: 4px 0 6px;\n  font-weight: var(--font-weight-bold);\n  letter-spacing: -0.2px;\n}\n\n.form-subtitle {\n  font-size: var(--font-size-paragraph);\n  color: var(--color-header-subtext);\n  margin: 0 0 16px;\n  line-height: 1.5;\n}\n\n/* ===== Form fields ===== */\n.form-field {\n  display: grid;\n  gap: 6px;\n  margin-bottom: 14px;\n}\n\n.form-field label {\n  font-size: var(--font-size-label);\n  color: var(--color-label);\n  font-weight: 600;\n}\n\n.form-field label .required {\n  color: var(--color-required);\n  margin-left: 2px;\n}\n\n/* Inputs / selects / textareas */\ninput[type=\"text\"],\ninput[type=\"email\"],\ninput[type=\"number\"],\ninput[type=\"search\"],\ntextarea,\nselect {\n  width: 100%;\n  appearance: none;\n  border: 1px solid var(--color-input-border);\n  border-radius: var(--border-radius-input);\n  padding: 12px 14px;\n  font-size: var(--font-size-input);\n  color: var(--color-input-text);\n  background: #fff;\n  transition: border-color .15s ease, box-shadow .15s ease, transform .05s ease;\n}\n\ninput::placeholder,\ntextarea::placeholder {\n  opacity: var(--opacity-placeholder);\n}\n\n/* Hover / focus */\ninput:hover,\ntextarea:hover,\nselect:hover {\n  border-color: #cfd5e2;\n}\n\ninput:focus,\ntextarea:focus,\nselect:focus {\n  outline: none;\n  border-color: var(--color-focus-border);\n  box-shadow: 0 0 0 4px rgba(90, 76, 194, .12);\n}\n\n/* Invalid */\n.is-invalid,\ninput[aria-invalid=\"true\"],\ntextarea[aria-invalid=\"true\"],\nselect[aria-invalid=\"true\"] {\n  border-color: var(--color-error);\n  box-shadow: 0 0 0 4px rgba(234, 31, 48, .12);\n}\n\n/* Help / error text */\n.help-text {\n  font-size: 12px;\n  color: var(--color-link);\n}\n\n.error-text {\n  font-size: var(--font-size-error);\n  color: var(--color-error);\n  margin-top: 4px;\n}\n\n/* ===== File input (custom) ===== */\n.input-file {\n  position: relative;\n}\n\n.input-file input[type=\"file\"] {\n  position: absolute;\n  inset: 0;\n  opacity: 0;\n  cursor: pointer;\n}\n\n.input-file .file-ui {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 10px;\n  border: 1px dashed var(--color-input-border);\n  border-radius: var(--border-radius-input);\n  padding: 12px 14px;\n  color: var(--color-input-text);\n  background: #fff;\n  transition: border-color .15s ease, box-shadow .15s ease;\n}\n\n.input-file .file-ui:hover {\n  border-color: #cfd5e2;\n}\n\n.input-file .file-ui:has(+ input[type=\"file\"]:focus) {\n  border-color: var(--color-focus-border);\n  box-shadow: 0 0 0 4px rgba(90, 76, 194, .12);\n}\n\n/* ===== Checkboxes / radios (accessible but nicer) ===== */\ninput[type=\"checkbox\"], input[type=\"radio\"] {\n  accent-color: var(--color-focus-border);\n  width: var(--checkbox-size);\n  height: var(--checkbox-size);\n}\n\n/* ===== Buttons ===== */\n.actions,\n.form-actions {\n  margin-top: 8px;\n}\n\nbutton[type=\"submit\"],\n.button-submit {\n  width: 100%;\n  height: var(--submit-btn-height);\n  background: var(--color-submit-btn-bg);\n  color: var(--color-submit-btn-text);\n  border: 1px solid transparent;\n  border-radius: var(--border-radius-input);\n  font-size: 15px;\n  font-weight: 700;\n  letter-spacing: .2px;\n  cursor: pointer;\n  transition: transform .05s ease, filter .15s ease, box-shadow .15s ease;\n  box-shadow: 0 6px 18px rgba(255, 109, 90, .25);\n}\n\nbutton[type=\"submit\"]:hover {\n  filter: brightness(0.98);\n  transform: translateY(-1px);\n  box-shadow: 0 8px 24px rgba(255, 109, 90, .28);\n}\n\nbutton[type=\"submit\"]:active {\n  transform: translateY(0);\n  box-shadow: 0 6px 18px rgba(255, 109, 90, .22);\n}\n\nbutton[disabled] {\n  opacity: .6;\n  cursor: not-allowed;\n}\n\n/* Secondary link under button (e.g., “Clear form”) */\n.clear-link {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n  margin-top: 10px;\n  font-size: var(--font-size-link);\n  color: var(--color-link);\n  text-decoration: none;\n}\n.clear-link:hover { text-decoration: underline; }\n\n/* ===== Footer / “Automated with n8n” ===== */\n.form-footer {\n  margin: 10px auto 24px;\n  max-width: var(--container-width);\n  text-align: center;\n  color: var(--color-link);\n  font-size: var(--font-size-link);\n}\n\n/* ===== Responsive ===== */\n@media (max-width: 520px) {\n  .container, .form-wrapper, .n8n-form {\n    margin: 20px auto;\n    padding: 0 10px;\n  }\n  .form-card { padding: 20px; }\n  .form-card h1, h1.form-title { font-size: 18px; }\n  .form-subtitle { font-size: 13px; }\n}\n\n/* ===== Optional: Dark mode (auto) ===== */\n@media (prefers-color-scheme: dark) {\n  body {\n    background:\n      radial-gradient(1200px 800px at 10% -10%, #272a33 0%, transparent 60%),\n      radial-gradient(1000px 700px at 110% 0%, #2c2433 0%, transparent 55%),\n      #16181d;\n    color: #d8dbe3;\n  }\n\n  .test-notice {\n    background: #2a2115;\n    border-color: #3a2b18;\n    color: #ffce74;\n  }\n\n  .form-card {\n    background: #1c1f27;\n    border-color: #2a2f3a;\n    box-shadow: 0 8px 24px rgba(0,0,0,.35);\n  }\n\n  .form-card h1, h1.form-title { color: #e9ebf3; }\n  .form-subtitle { color: #a6adbb; }\n\n  input, textarea, select {\n    background: #11151c;\n    border-color: #2a2f3a;\n    color: #d8dbe3;\n  }\n  input:hover, textarea:hover, select:hover { border-color: #3a4250; }\n  input:focus, textarea:focus, select:focus {\n    border-color: #b7a8ff;\n    box-shadow: 0 0 0 4px rgba(183,168,255,.18);\n  }\n\n  .help-text { color: #9aa3b2; }\n\n  button[type=\"submit\"],\n  .button-submit {\n    box-shadow: 0 10px 26px rgba(255,109,90,.34);\n  }\n\n  .form-footer { color: #9aa3b2; }\n}\n",
          "buttonLabel": "Send question"
        },
        "formTitle": "Monthly HR meeting",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Your name",
              "requiredField": true
            },
            {
              "fieldLabel": "Department"
            },
            {
              "fieldType": "email",
              "fieldLabel": "Internal email"
            },
            {
              "fieldLabel": "Your question",
              "requiredField": true
            }
          ]
        },
        "responseMode": "lastNode",
        "formDescription": "Do you have any questions? Let us know below and we'll answer them soon at our monthly meeting."
      },
      "typeVersion": 2.3
    },
    {
      "id": "eeff26db-3267-4126-81e1-df6996106aaf",
      "name": "Agregar pregunta a la base de datos",
      "type": "n8n-nodes-base.mySql",
      "position": [
        208,
        -144
      ],
      "parameters": {
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "hr_questions",
          "cachedResultName": "hr_questions"
        },
        "options": {},
        "dataMode": "defineBelow",
        "valuesToSend": {
          "values": [
            {
              "value": "={{ $json['Your name'] }}",
              "column": "name"
            },
            {
              "value": "={{ $json.Department }}",
              "column": "department"
            },
            {
              "value": "={{ $json['Internal email'] }}",
              "column": "email"
            },
            {
              "value": "={{ $json['Your question'] }}",
              "column": "question"
            },
            {
              "value": "={{ $json.submittedAt.toDateTime() }}",
              "column": "created_at"
            }
          ]
        }
      },
      "credentials": {
        "mySql": {
          "id": "sQeUBEQkBvNWbM2y",
          "name": "MySQL - Estudos"
        }
      },
      "typeVersion": 2.5
    },
    {
      "id": "4ad67f5f-8a7d-4d70-9c3e-a3d250c2562d",
      "name": "Devolver formulario",
      "type": "n8n-nodes-base.form",
      "position": [
        624,
        -144
      ],
      "webhookId": "c2e31794-9f17-43a6-806c-05fca8b2c01d",
      "parameters": {
        "options": {
          "customCss": "/* ===== Base layout ===== */\nhtml, body {\n  height: 100%;\n  font-family: var(--font-family);\n  font-weight: var(--font-weight-normal);\n  font-size: var(--font-size-body);\n  background:\n    radial-gradient(1200px 800px at 10% -10%, #f0f2ff 0%, transparent 60%),\n    radial-gradient(1000px 700px at 110% 0%, #fef3f0 0%, transparent 55%),\n    var(--color-background);\n  color: var(--color-html-text);\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\n.container, .form-wrapper, .n8n-form {\n  max-width: var(--container-width);\n  margin: 32px auto;\n  padding: 0 12px;\n}\n\n/* ===== Test banner (top) ===== */\n.test-notice {\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  margin: 0 auto 12px;\n  max-width: var(--container-width);\n  background: var(--color-test-notice-bg);\n  border: 1px solid var(--color-test-notice-border);\n  color: var(--color-test-notice-text);\n  padding: var(--padding-test-notice-vertical) var(--padding-test-notice-horizontal);\n  border-radius: var(--border-radius-input);\n  font-size: var(--font-size-test-notice);\n}\n\n/* ===== Card ===== */\n.form-card {\n  background: var(--color-card-bg);\n  border: 1px solid var(--color-card-border);\n  border-radius: var(--border-radius-card);\n  box-shadow: var(--box-shadow-card);\n  padding: var(--padding-card);\n  margin-bottom: var(--margin-bottom-card);\n}\n\n/* ===== Headings & subtitle ===== */\n.form-card h1,\nh1.form-title {\n  font-size: var(--font-size-header);\n  color: var(--color-header);\n  margin: 4px 0 6px;\n  font-weight: var(--font-weight-bold);\n  letter-spacing: -0.2px;\n}\n\n.form-subtitle {\n  font-size: var(--font-size-paragraph);\n  color: var(--color-header-subtext);\n  margin: 0 0 16px;\n  line-height: 1.5;\n}\n\n/* ===== Form fields ===== */\n.form-field {\n  display: grid;\n  gap: 6px;\n  margin-bottom: 14px;\n}\n\n.form-field label {\n  font-size: var(--font-size-label);\n  color: var(--color-label);\n  font-weight: 600;\n}\n\n.form-field label .required {\n  color: var(--color-required);\n  margin-left: 2px;\n}\n\n/* Inputs / selects / textareas */\ninput[type=\"text\"],\ninput[type=\"email\"],\ninput[type=\"number\"],\ninput[type=\"search\"],\ntextarea,\nselect {\n  width: 100%;\n  appearance: none;\n  border: 1px solid var(--color-input-border);\n  border-radius: var(--border-radius-input);\n  padding: 12px 14px;\n  font-size: var(--font-size-input);\n  color: var(--color-input-text);\n  background: #fff;\n  transition: border-color .15s ease, box-shadow .15s ease, transform .05s ease;\n}\n\ninput::placeholder,\ntextarea::placeholder {\n  opacity: var(--opacity-placeholder);\n}\n\n/* Hover / focus */\ninput:hover,\ntextarea:hover,\nselect:hover {\n  border-color: #cfd5e2;\n}\n\ninput:focus,\ntextarea:focus,\nselect:focus {\n  outline: none;\n  border-color: var(--color-focus-border);\n  box-shadow: 0 0 0 4px rgba(90, 76, 194, .12);\n}\n\n/* Invalid */\n.is-invalid,\ninput[aria-invalid=\"true\"],\ntextarea[aria-invalid=\"true\"],\nselect[aria-invalid=\"true\"] {\n  border-color: var(--color-error);\n  box-shadow: 0 0 0 4px rgba(234, 31, 48, .12);\n}\n\n/* Help / error text */\n.help-text {\n  font-size: 12px;\n  color: var(--color-link);\n}\n\n.error-text {\n  font-size: var(--font-size-error);\n  color: var(--color-error);\n  margin-top: 4px;\n}\n\n/* ===== File input (custom) ===== */\n.input-file {\n  position: relative;\n}\n\n.input-file input[type=\"file\"] {\n  position: absolute;\n  inset: 0;\n  opacity: 0;\n  cursor: pointer;\n}\n\n.input-file .file-ui {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 10px;\n  border: 1px dashed var(--color-input-border);\n  border-radius: var(--border-radius-input);\n  padding: 12px 14px;\n  color: var(--color-input-text);\n  background: #fff;\n  transition: border-color .15s ease, box-shadow .15s ease;\n}\n\n.input-file .file-ui:hover {\n  border-color: #cfd5e2;\n}\n\n.input-file .file-ui:has(+ input[type=\"file\"]:focus) {\n  border-color: var(--color-focus-border);\n  box-shadow: 0 0 0 4px rgba(90, 76, 194, .12);\n}\n\n/* ===== Checkboxes / radios (accessible but nicer) ===== */\ninput[type=\"checkbox\"], input[type=\"radio\"] {\n  accent-color: var(--color-focus-border);\n  width: var(--checkbox-size);\n  height: var(--checkbox-size);\n}\n\n/* ===== Buttons ===== */\n.actions,\n.form-actions {\n  margin-top: 8px;\n}\n\nbutton[type=\"submit\"],\n.button-submit {\n  width: 100%;\n  height: var(--submit-btn-height);\n  background: var(--color-submit-btn-bg);\n  color: var(--color-submit-btn-text);\n  border: 1px solid transparent;\n  border-radius: var(--border-radius-input);\n  font-size: 15px;\n  font-weight: 700;\n  letter-spacing: .2px;\n  cursor: pointer;\n  transition: transform .05s ease, filter .15s ease, box-shadow .15s ease;\n  box-shadow: 0 6px 18px rgba(255, 109, 90, .25);\n}\n\nbutton[type=\"submit\"]:hover {\n  filter: brightness(0.98);\n  transform: translateY(-1px);\n  box-shadow: 0 8px 24px rgba(255, 109, 90, .28);\n}\n\nbutton[type=\"submit\"]:active {\n  transform: translateY(0);\n  box-shadow: 0 6px 18px rgba(255, 109, 90, .22);\n}\n\nbutton[disabled] {\n  opacity: .6;\n  cursor: not-allowed;\n}\n\n/* Secondary link under button (e.g., “Clear form”) */\n.clear-link {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n  margin-top: 10px;\n  font-size: var(--font-size-link);\n  color: var(--color-link);\n  text-decoration: none;\n}\n.clear-link:hover { text-decoration: underline; }\n\n/* ===== Footer / “Automated with n8n” ===== */\n.form-footer {\n  margin: 10px auto 24px;\n  max-width: var(--container-width);\n  text-align: center;\n  color: var(--color-link);\n  font-size: var(--font-size-link);\n}\n\n/* ===== Responsive ===== */\n@media (max-width: 520px) {\n  .container, .form-wrapper, .n8n-form {\n    margin: 20px auto;\n    padding: 0 10px;\n  }\n  .form-card { padding: 20px; }\n  .form-card h1, h1.form-title { font-size: 18px; }\n  .form-subtitle { font-size: 13px; }\n}\n\n/* ===== Optional: Dark mode (auto) ===== */\n@media (prefers-color-scheme: dark) {\n  body {\n    background:\n      radial-gradient(1200px 800px at 10% -10%, #272a33 0%, transparent 60%),\n      radial-gradient(1000px 700px at 110% 0%, #2c2433 0%, transparent 55%),\n      #16181d;\n    color: #d8dbe3;\n  }\n\n  .test-notice {\n    background: #2a2115;\n    border-color: #3a2b18;\n    color: #ffce74;\n  }\n\n  .form-card {\n    background: #1c1f27;\n    border-color: #2a2f3a;\n    box-shadow: 0 8px 24px rgba(0,0,0,.35);\n  }\n\n  .form-card h1, h1.form-title { color: #e9ebf3; }\n  .form-subtitle { color: #a6adbb; }\n\n  input, textarea, select {\n    background: #11151c;\n    border-color: #2a2f3a;\n    color: #d8dbe3;\n  }\n  input:hover, textarea:hover, select:hover { border-color: #3a4250; }\n  input:focus, textarea:focus, select:focus {\n    border-color: #b7a8ff;\n    box-shadow: 0 0 0 4px rgba(183,168,255,.18);\n  }\n\n  .help-text { color: #9aa3b2; }\n\n  button[type=\"submit\"],\n  .button-submit {\n    box-shadow: 0 10px 26px rgba(255,109,90,.34);\n  }\n\n  .form-footer { color: #9aa3b2; }\n}\n"
        },
        "operation": "completion",
        "completionTitle": "Your question has been sent",
        "completionMessage": "It will be answered soon at our monthly meeting."
      },
      "typeVersion": 2.3
    },
    {
      "id": "0bf75f31-39e1-4011-837d-6da8bd431c04",
      "name": "Formulario para obtener preguntas",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -208,
        288
      ],
      "webhookId": "e941986f-9a36-40a5-a0fa-ac522cea9a28",
      "parameters": {
        "options": {
          "customCss": "/* ===== Base layout ===== */\nhtml, body {\n  height: 100%;\n  font-family: var(--font-family);\n  font-weight: var(--font-weight-normal);\n  font-size: var(--font-size-body);\n  background:\n    radial-gradient(1200px 800px at 10% -10%, #f0f2ff 0%, transparent 60%),\n    radial-gradient(1000px 700px at 110% 0%, #fef3f0 0%, transparent 55%),\n    var(--color-background);\n  color: var(--color-html-text);\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\n.container, .form-wrapper, .n8n-form {\n  max-width: var(--container-width);\n  margin: 32px auto;\n  padding: 0 12px;\n}\n\n/* ===== Test banner (top) ===== */\n.test-notice {\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  margin: 0 auto 12px;\n  max-width: var(--container-width);\n  background: var(--color-test-notice-bg);\n  border: 1px solid var(--color-test-notice-border);\n  color: var(--color-test-notice-text);\n  padding: var(--padding-test-notice-vertical) var(--padding-test-notice-horizontal);\n  border-radius: var(--border-radius-input);\n  font-size: var(--font-size-test-notice);\n}\n\n/* ===== Card ===== */\n.form-card {\n  background: var(--color-card-bg);\n  border: 1px solid var(--color-card-border);\n  border-radius: var(--border-radius-card);\n  box-shadow: var(--box-shadow-card);\n  padding: var(--padding-card);\n  margin-bottom: var(--margin-bottom-card);\n}\n\n/* ===== Headings & subtitle ===== */\n.form-card h1,\nh1.form-title {\n  font-size: var(--font-size-header);\n  color: var(--color-header);\n  margin: 4px 0 6px;\n  font-weight: var(--font-weight-bold);\n  letter-spacing: -0.2px;\n}\n\n.form-subtitle {\n  font-size: var(--font-size-paragraph);\n  color: var(--color-header-subtext);\n  margin: 0 0 16px;\n  line-height: 1.5;\n}\n\n/* ===== Form fields ===== */\n.form-field {\n  display: grid;\n  gap: 6px;\n  margin-bottom: 14px;\n}\n\n.form-field label {\n  font-size: var(--font-size-label);\n  color: var(--color-label);\n  font-weight: 600;\n}\n\n.form-field label .required {\n  color: var(--color-required);\n  margin-left: 2px;\n}\n\n/* Inputs / selects / textareas */\ninput[type=\"text\"],\ninput[type=\"email\"],\ninput[type=\"number\"],\ninput[type=\"search\"],\ntextarea,\nselect {\n  width: 100%;\n  appearance: none;\n  border: 1px solid var(--color-input-border);\n  border-radius: var(--border-radius-input);\n  padding: 12px 14px;\n  font-size: var(--font-size-input);\n  color: var(--color-input-text);\n  background: #fff;\n  transition: border-color .15s ease, box-shadow .15s ease, transform .05s ease;\n}\n\ninput::placeholder,\ntextarea::placeholder {\n  opacity: var(--opacity-placeholder);\n}\n\n/* Hover / focus */\ninput:hover,\ntextarea:hover,\nselect:hover {\n  border-color: #cfd5e2;\n}\n\ninput:focus,\ntextarea:focus,\nselect:focus {\n  outline: none;\n  border-color: var(--color-focus-border);\n  box-shadow: 0 0 0 4px rgba(90, 76, 194, .12);\n}\n\n/* Invalid */\n.is-invalid,\ninput[aria-invalid=\"true\"],\ntextarea[aria-invalid=\"true\"],\nselect[aria-invalid=\"true\"] {\n  border-color: var(--color-error);\n  box-shadow: 0 0 0 4px rgba(234, 31, 48, .12);\n}\n\n/* Help / error text */\n.help-text {\n  font-size: 12px;\n  color: var(--color-link);\n}\n\n.error-text {\n  font-size: var(--font-size-error);\n  color: var(--color-error);\n  margin-top: 4px;\n}\n\n/* ===== File input (custom) ===== */\n.input-file {\n  position: relative;\n}\n\n.input-file input[type=\"file\"] {\n  position: absolute;\n  inset: 0;\n  opacity: 0;\n  cursor: pointer;\n}\n\n.input-file .file-ui {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 10px;\n  border: 1px dashed var(--color-input-border);\n  border-radius: var(--border-radius-input);\n  padding: 12px 14px;\n  color: var(--color-input-text);\n  background: #fff;\n  transition: border-color .15s ease, box-shadow .15s ease;\n}\n\n.input-file .file-ui:hover {\n  border-color: #cfd5e2;\n}\n\n.input-file .file-ui:has(+ input[type=\"file\"]:focus) {\n  border-color: var(--color-focus-border);\n  box-shadow: 0 0 0 4px rgba(90, 76, 194, .12);\n}\n\n/* ===== Checkboxes / radios (accessible but nicer) ===== */\ninput[type=\"checkbox\"], input[type=\"radio\"] {\n  accent-color: var(--color-focus-border);\n  width: var(--checkbox-size);\n  height: var(--checkbox-size);\n}\n\n/* ===== Buttons ===== */\n.actions,\n.form-actions {\n  margin-top: 8px;\n}\n\nbutton[type=\"submit\"],\n.button-submit {\n  width: 100%;\n  height: var(--submit-btn-height);\n  background: var(--color-submit-btn-bg);\n  color: var(--color-submit-btn-text);\n  border: 1px solid transparent;\n  border-radius: var(--border-radius-input);\n  font-size: 15px;\n  font-weight: 700;\n  letter-spacing: .2px;\n  cursor: pointer;\n  transition: transform .05s ease, filter .15s ease, box-shadow .15s ease;\n  box-shadow: 0 6px 18px rgba(255, 109, 90, .25);\n}\n\nbutton[type=\"submit\"]:hover {\n  filter: brightness(0.98);\n  transform: translateY(-1px);\n  box-shadow: 0 8px 24px rgba(255, 109, 90, .28);\n}\n\nbutton[type=\"submit\"]:active {\n  transform: translateY(0);\n  box-shadow: 0 6px 18px rgba(255, 109, 90, .22);\n}\n\nbutton[disabled] {\n  opacity: .6;\n  cursor: not-allowed;\n}\n\n/* Secondary link under button (e.g., “Clear form”) */\n.clear-link {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n  margin-top: 10px;\n  font-size: var(--font-size-link);\n  color: var(--color-link);\n  text-decoration: none;\n}\n.clear-link:hover { text-decoration: underline; }\n\n/* ===== Footer / “Automated with n8n” ===== */\n.form-footer {\n  margin: 10px auto 24px;\n  max-width: var(--container-width);\n  text-align: center;\n  color: var(--color-link);\n  font-size: var(--font-size-link);\n}\n\n/* ===== Responsive ===== */\n@media (max-width: 520px) {\n  .container, .form-wrapper, .n8n-form {\n    margin: 20px auto;\n    padding: 0 10px;\n  }\n  .form-card { padding: 20px; }\n  .form-card h1, h1.form-title { font-size: 18px; }\n  .form-subtitle { font-size: 13px; }\n}\n\n/* ===== Optional: Dark mode (auto) ===== */\n@media (prefers-color-scheme: dark) {\n  body {\n    background:\n      radial-gradient(1200px 800px at 10% -10%, #272a33 0%, transparent 60%),\n      radial-gradient(1000px 700px at 110% 0%, #2c2433 0%, transparent 55%),\n      #16181d;\n    color: #d8dbe3;\n  }\n\n  .test-notice {\n    background: #2a2115;\n    border-color: #3a2b18;\n    color: #ffce74;\n  }\n\n  .form-card {\n    background: #1c1f27;\n    border-color: #2a2f3a;\n    box-shadow: 0 8px 24px rgba(0,0,0,.35);\n  }\n\n  .form-card h1, h1.form-title { color: #e9ebf3; }\n  .form-subtitle { color: #a6adbb; }\n\n  input, textarea, select {\n    background: #11151c;\n    border-color: #2a2f3a;\n    color: #d8dbe3;\n  }\n  input:hover, textarea:hover, select:hover { border-color: #3a4250; }\n  input:focus, textarea:focus, select:focus {\n    border-color: #b7a8ff;\n    box-shadow: 0 0 0 4px rgba(183,168,255,.18);\n  }\n\n  .help-text { color: #9aa3b2; }\n\n  button[type=\"submit\"],\n  .button-submit {\n    box-shadow: 0 10px 26px rgba(255,109,90,.34);\n  }\n\n  .form-footer { color: #9aa3b2; }\n}",
          "buttonLabel": "Get Questions"
        },
        "formTitle": "Monthly HR meeting",
        "formFields": {
          "values": [
            {
              "fieldType": "date",
              "fieldLabel": "Of the day"
            },
            {
              "fieldType": "date",
              "fieldLabel": "Until the day"
            }
          ]
        },
        "responseMode": "lastNode",
        "formDescription": "Get top questions received"
      },
      "typeVersion": 2.3
    },
    {
      "id": "e34867e7-8e27-4a2a-93be-8a67ed646e22",
      "name": "Obtener consultas de la base de datos",
      "type": "n8n-nodes-base.mySql",
      "position": [
        192,
        288
      ],
      "parameters": {
        "query": "SELECT *\nfrom hr_questions\nWHERE created_at BETWEEN '{{ $json['Of the day'] }}'\nAND '{{ $json['Until the day'] }}';",
        "options": {},
        "operation": "executeQuery"
      },
      "credentials": {
        "mySql": {
          "id": "sQeUBEQkBvNWbM2y",
          "name": "MySQL - Estudos"
        }
      },
      "typeVersion": 2.5
    },
    {
      "id": "28a3be94-52e4-47d1-a37d-b43edb42a0c0",
      "name": "Devolver guion de la reunión",
      "type": "n8n-nodes-base.form",
      "position": [
        2992,
        304
      ],
      "webhookId": "c2e31794-9f17-43a6-806c-05fca8b2c01d",
      "parameters": {
        "options": {
          "customCss": "/* ===== Base layout ===== */\nhtml, body {\n  height: 100%;\n  font-family: var(--font-family);\n  font-weight: var(--font-weight-normal);\n  font-size: var(--font-size-body);\n  background:\n    radial-gradient(1200px 800px at 10% -10%, #f0f2ff 0%, transparent 60%),\n    radial-gradient(1000px 700px at 110% 0%, #fef3f0 0%, transparent 55%),\n    var(--color-background);\n  color: var(--color-html-text);\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\n.container, .form-wrapper, .n8n-form {\n  max-width: var(--container-width);\n  margin: 32px auto;\n  padding: 0 12px;\n}\n\n/* ===== Test banner (top) ===== */\n.test-notice {\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  margin: 0 auto 12px;\n  max-width: var(--container-width);\n  background: var(--color-test-notice-bg);\n  border: 1px solid var(--color-test-notice-border);\n  color: var(--color-test-notice-text);\n  padding: var(--padding-test-notice-vertical) var(--padding-test-notice-horizontal);\n  border-radius: var(--border-radius-input);\n  font-size: var(--font-size-test-notice);\n}\n\n/* ===== Card ===== */\n.form-card {\n  background: var(--color-card-bg);\n  border: 1px solid var(--color-card-border);\n  border-radius: var(--border-radius-card);\n  box-shadow: var(--box-shadow-card);\n  padding: var(--padding-card);\n  margin-bottom: var(--margin-bottom-card);\n}\n\n/* ===== Headings & subtitle ===== */\n.form-card h1,\nh1.form-title {\n  font-size: var(--font-size-header);\n  color: var(--color-header);\n  margin: 4px 0 6px;\n  font-weight: var(--font-weight-bold);\n  letter-spacing: -0.2px;\n}\n\n.form-subtitle {\n  font-size: var(--font-size-paragraph);\n  color: var(--color-header-subtext);\n  margin: 0 0 16px;\n  line-height: 1.5;\n}\n\n/* ===== Form fields ===== */\n.form-field {\n  display: grid;\n  gap: 6px;\n  margin-bottom: 14px;\n}\n\n.form-field label {\n  font-size: var(--font-size-label);\n  color: var(--color-label);\n  font-weight: 600;\n}\n\n.form-field label .required {\n  color: var(--color-required);\n  margin-left: 2px;\n}\n\n/* Inputs / selects / textareas */\ninput[type=\"text\"],\ninput[type=\"email\"],\ninput[type=\"number\"],\ninput[type=\"search\"],\ntextarea,\nselect {\n  width: 100%;\n  appearance: none;\n  border: 1px solid var(--color-input-border);\n  border-radius: var(--border-radius-input);\n  padding: 12px 14px;\n  font-size: var(--font-size-input);\n  color: var(--color-input-text);\n  background: #fff;\n  transition: border-color .15s ease, box-shadow .15s ease, transform .05s ease;\n}\n\ninput::placeholder,\ntextarea::placeholder {\n  opacity: var(--opacity-placeholder);\n}\n\n/* Hover / focus */\ninput:hover,\ntextarea:hover,\nselect:hover {\n  border-color: #cfd5e2;\n}\n\ninput:focus,\ntextarea:focus,\nselect:focus {\n  outline: none;\n  border-color: var(--color-focus-border);\n  box-shadow: 0 0 0 4px rgba(90, 76, 194, .12);\n}\n\n/* Invalid */\n.is-invalid,\ninput[aria-invalid=\"true\"],\ntextarea[aria-invalid=\"true\"],\nselect[aria-invalid=\"true\"] {\n  border-color: var(--color-error);\n  box-shadow: 0 0 0 4px rgba(234, 31, 48, .12);\n}\n\n/* Help / error text */\n.help-text {\n  font-size: 12px;\n  color: var(--color-link);\n}\n\n.error-text {\n  font-size: var(--font-size-error);\n  color: var(--color-error);\n  margin-top: 4px;\n}\n\n/* ===== File input (custom) ===== */\n.input-file {\n  position: relative;\n}\n\n.input-file input[type=\"file\"] {\n  position: absolute;\n  inset: 0;\n  opacity: 0;\n  cursor: pointer;\n}\n\n.input-file .file-ui {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 10px;\n  border: 1px dashed var(--color-input-border);\n  border-radius: var(--border-radius-input);\n  padding: 12px 14px;\n  color: var(--color-input-text);\n  background: #fff;\n  transition: border-color .15s ease, box-shadow .15s ease;\n}\n\n.input-file .file-ui:hover {\n  border-color: #cfd5e2;\n}\n\n.input-file .file-ui:has(+ input[type=\"file\"]:focus) {\n  border-color: var(--color-focus-border);\n  box-shadow: 0 0 0 4px rgba(90, 76, 194, .12);\n}\n\n/* ===== Checkboxes / radios (accessible but nicer) ===== */\ninput[type=\"checkbox\"], input[type=\"radio\"] {\n  accent-color: var(--color-focus-border);\n  width: var(--checkbox-size);\n  height: var(--checkbox-size);\n}\n\n/* ===== Buttons ===== */\n.actions,\n.form-actions {\n  margin-top: 8px;\n}\n\nbutton[type=\"submit\"],\n.button-submit {\n  width: 100%;\n  height: var(--submit-btn-height);\n  background: var(--color-submit-btn-bg);\n  color: var(--color-submit-btn-text);\n  border: 1px solid transparent;\n  border-radius: var(--border-radius-input);\n  font-size: 15px;\n  font-weight: 700;\n  letter-spacing: .2px;\n  cursor: pointer;\n  transition: transform .05s ease, filter .15s ease, box-shadow .15s ease;\n  box-shadow: 0 6px 18px rgba(255, 109, 90, .25);\n}\n\nbutton[type=\"submit\"]:hover {\n  filter: brightness(0.98);\n  transform: translateY(-1px);\n  box-shadow: 0 8px 24px rgba(255, 109, 90, .28);\n}\n\nbutton[type=\"submit\"]:active {\n  transform: translateY(0);\n  box-shadow: 0 6px 18px rgba(255, 109, 90, .22);\n}\n\nbutton[disabled] {\n  opacity: .6;\n  cursor: not-allowed;\n}\n\n/* Secondary link under button (e.g., “Clear form”) */\n.clear-link {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n  margin-top: 10px;\n  font-size: var(--font-size-link);\n  color: var(--color-link);\n  text-decoration: none;\n}\n.clear-link:hover { text-decoration: underline; }\n\n/* ===== Footer / “Automated with n8n” ===== */\n.form-footer {\n  margin: 10px auto 24px;\n  max-width: var(--container-width);\n  text-align: center;\n  color: var(--color-link);\n  font-size: var(--font-size-link);\n}\n\n/* ===== Responsive ===== */\n@media (max-width: 520px) {\n  .container, .form-wrapper, .n8n-form {\n    margin: 20px auto;\n    padding: 0 10px;\n  }\n  .form-card { padding: 20px; }\n  .form-card h1, h1.form-title { font-size: 18px; }\n  .form-subtitle { font-size: 13px; }\n}\n\n/* ===== Optional: Dark mode (auto) ===== */\n@media (prefers-color-scheme: dark) {\n  body {\n    background:\n      radial-gradient(1200px 800px at 10% -10%, #272a33 0%, transparent 60%),\n      radial-gradient(1000px 700px at 110% 0%, #2c2433 0%, transparent 55%),\n      #16181d;\n    color: #d8dbe3;\n  }\n\n  .test-notice {\n    background: #2a2115;\n    border-color: #3a2b18;\n    color: #ffce74;\n  }\n\n  .form-card {\n    background: #1c1f27;\n    border-color: #2a2f3a;\n    box-shadow: 0 8px 24px rgba(0,0,0,.35);\n  }\n\n  .form-card h1, h1.form-title { color: #e9ebf3; }\n  .form-subtitle { color: #a6adbb; }\n\n  input, textarea, select {\n    background: #11151c;\n    border-color: #2a2f3a;\n    color: #d8dbe3;\n  }\n  input:hover, textarea:hover, select:hover { border-color: #3a4250; }\n  input:focus, textarea:focus, select:focus {\n    border-color: #b7a8ff;\n    box-shadow: 0 0 0 4px rgba(183,168,255,.18);\n  }\n\n  .help-text { color: #9aa3b2; }\n\n  button[type=\"submit\"],\n  .button-submit {\n    box-shadow: 0 10px 26px rgba(255,109,90,.34);\n  }\n\n  .form-footer { color: #9aa3b2; }\n}\n"
        },
        "operation": "completion",
        "respondWith": "returnBinary",
        "completionTitle": "Questions collected and meeting scheduled with employees who responded to the form",
        "completionMessage": "=Meeting scheduled:<br>\n{{ $json.output.meeting.title }}<br>\nAttendees: {{ $json.output.meeting.attendees_count }}<br>\nStart: {{ $json.output.meeting.start }}<br>\nEnd: {{ $json.output.meeting.end }}<br><br>\nThe .txt file with the employees' main questions will be automatically downloaded immediately."
      },
      "typeVersion": 2.3
    },
    {
      "id": "487e1170-ed55-4273-93b0-38df2dc73452",
      "name": "Obtener start_date y end_date de la reunión",
      "type": "n8n-nodes-base.set",
      "position": [
        1008,
        288
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "bce3c461-e509-4728-8546-22aae16b6d84",
              "name": "start_date",
              "type": "string",
              "value": "={{ \n  (() => {\n    const now = new Date();\n    const year = now.getFullYear();\n    const month = now.getMonth(); // 0 = janeiro\n\n    // último dia do mês\n    const lastDay = new Date(year, month + 1, 0);\n\n    // voltar até encontrar sexta (5)\n    while (lastDay.getDay() !== 5) {\n      lastDay.setDate(lastDay.getDate() - 1);\n    }\n\n    // definir hora da reunião (16h00)\n    lastDay.setHours(16, 0, 0, 0);\n\n    return lastDay.toISOString();\n  })()\n}}\n"
            },
            {
              "id": "4200c0fd-8dd9-492f-87dd-f8dd0ff92858",
              "name": "end_date",
              "type": "string",
              "value": "={{ \n  (() => {\n    const now = new Date();\n    const year = now.getFullYear();\n    const month = now.getMonth();\n\n    const lastDay = new Date(year, month + 1, 0);\n    while (lastDay.getDay() !== 5) {\n      lastDay.setDate(lastDay.getDate() - 1);\n    }\n\n    // horário fim = 17h00\n    lastDay.setHours(17, 0, 0, 0);\n\n    return lastDay.toISOString();\n  })()\n}}\n"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "c038c2ed-74c0-4ab7-8377-564c4bb7d6db",
      "name": "Agregar preguntas",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        624,
        288
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData",
        "destinationFieldName": "questions"
      },
      "typeVersion": 1
    },
    {
      "id": "ecacc9e8-a321-496e-b103-f66e3e48a0f8",
      "name": "Nota adhesiva",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -320,
        -832
      ],
      "parameters": {
        "color": 4,
        "width": 848,
        "height": 448,
        "content": "## Monthly HR Q&A — End-to-end flow\n\nThis template collects employees’ questions via a form, stores them, and later lets HR:\n1) Fetch questions by date range,\n2) Deduplicate/cluster similar questions,\n3) Generate a clear script (text) for the meeting,\n4) Create a Google Calendar event with a Meet link for the last Friday of the current month,\n5) Return a confirmation page and auto-download the script (.txt).\n\n**Security**\n- No API keys hardcoded. Use credentials in nodes.\n- Avoid PII in public artifacts; keep emails internal only.\n\n**Success criteria**\n- Form submits to DB without errors,\n- AI Agent returns JSON with { meeting, script },\n- Calendar event is actually created (has event_id + meet_link),\n- Final page shows meeting info and downloads the script file.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "96cbd737-4482-4476-9f3b-c53c4810f7e5",
      "name": "Nota adhesiva1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -320,
        -368
      ],
      "parameters": {
        "color": 4,
        "width": 368,
        "height": 400,
        "content": "Collects employee inputs:\n- Your name (required)\n- Department\n- Internal email (required for follow-up)\n- Your question (required)\n\nStyled with custom CSS for better UX.\nOn submit → forwards to DB insert node.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "d15210c2-8094-4220-a097-5621639df4bd",
      "name": "Nota adhesiva2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        80,
        -368
      ],
      "parameters": {
        "width": 368,
        "height": 400,
        "content": "Writes to table: hr_questions\nColumns:\n- name, department, email, question\n- created_at = submittedAt.toDateTime()\n\nTip:\n- Validate email format on the Form if possible.\n- Keep questions in original language (used later by the Agent).\n"
      },
      "typeVersion": 1
    },
    {
      "id": "1892a011-bb06-4eb5-a033-1106fdd89b6e",
      "name": "Nota adhesiva3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        480,
        -368
      ],
      "parameters": {
        "color": 3,
        "width": 368,
        "height": 400,
        "content": "Thank-you/confirmation page for employees.\n\nMessaging:\n- Confirms the question has been received,\n- Explains questions will be addressed in the monthly HR Q&A meeting.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "7d6c8f68-ece5-4496-8a29-e8f2c894679d",
      "name": "Nota adhesiva4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -320,
        64
      ],
      "parameters": {
        "color": 4,
        "width": 368,
        "height": 400,
        "content": "HR utility form to select a date window:\n- \"Of the day\" → start date\n- \"Until the day\" → end date\n\nThese dates feed the SQL query to pull relevant questions from DB.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "62914b4b-2b0c-422f-976e-4a3ee4131045",
      "name": "Nota adhesiva5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        80,
        64
      ],
      "parameters": {
        "width": 368,
        "height": 400,
        "content": "SQL range query on hr_questions by created_at.\n\nCheck:\n- Date format matches DB column type (TIMESTAMP/DATE).\n- Consider timezone normalization in DB.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "1be5a326-490b-41a9-9b15-219ccd8c3b7e",
      "name": "Nota adhesiva6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        480,
        64
      ],
      "parameters": {
        "width": 368,
        "height": 400,
        "content": "Aggregates all rows into a single array: `questions`.\n\nThis array is passed to the AI Agent as the payload (JSON).\n"
      },
      "typeVersion": 1
    },
    {
      "id": "f6c84649-3757-4ecc-b16b-b246c04cc34e",
      "name": "Nota adhesiva7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        880,
        64
      ],
      "parameters": {
        "width": 368,
        "height": 400,
        "content": "Computes meeting start/end:\n- Last Friday of the current month,\n- 16:00–17:00 (local time).\n\nExpressions return ISO strings. Update logic if you want:\n- If the last Friday has already passed, move to next month.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "567689c8-2ca4-4e6e-b0d4-85b6fcdc1848",
      "name": "Nota adhesiva8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1280,
        -144
      ],
      "parameters": {
        "color": 5,
        "width": 752,
        "height": 864,
        "content": "Roles:\n1) Validate questions (non-empty, valid emails),\n2) Deduplicate/cluster by semantic similarity,\n3) Prioritize by frequency (ties: earliest created_at),\n4) CALL the tool \"Create an event in Google Calendar\" with:\n   - title: \"Monthly HR Q&A – {Month YYYY}\"\n   - start / end (from previous node)\n   - timezone: America/Sao_Paulo\n   - attendees: unique valid emails\n   - Meet enabled (conference)\n5) Return JSON:\n{\n  \"meeting\": { title, start, end, timezone, meet_link, event_id, attendees_count },\n  \"script\": \"TEXT (Markdown) — list of deduped questions with counts\"\n}\n\nImportant:\n- Only return the final JSON AFTER the calendar tool is called.\n- `script` is ONE text field (not an array).\n"
      },
      "typeVersion": 1
    },
    {
      "id": "ddf03f40-13c8-4e98-ab50-81ccb5394e1f",
      "name": "Nota adhesiva9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2064,
        64
      ],
      "parameters": {
        "width": 368,
        "height": 400,
        "content": "Converts `output.script` (text) → MeetingItinerary.txt\n\nThis file is automatically downloaded in the final step.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "72b7e6ce-3b32-46a6-ada6-bcfc7a0f8b08",
      "name": "Nota adhesiva10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2464,
        64
      ],
      "parameters": {
        "width": 368,
        "height": 400,
        "content": "Merges JSON output from the AI Agent with the generated file,\nso the final page can show event info and trigger the download.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "b04406c0-5577-4f2e-b15f-f1e7cce5a109",
      "name": "Nota adhesiva11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2864,
        64
      ],
      "parameters": {
        "color": 3,
        "width": 368,
        "height": 400,
        "content": "HR confirmation page:\n- Shows title, attendees_count, start/end,\n- Triggers download of MeetingItinerary.txt.\n\nTip:\n- Keep copy clear and actionable for HR.\n"
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "7e3a6fd2-a3ee-435f-b4fe-d74dc6ee2203",
  "connections": {
    "3eb9a6d5-3e1a-4761-aafe-4ec1c7fcf028": {
      "main": [
        [
          {
            "node": "28a3be94-52e4-47d1-a37d-b43edb42a0c0",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "fedb0008-1164-4c8c-b699-a4576ccb3f14": {
      "main": [
        [
          {
            "node": "65d92503-fad1-4816-88d4-9f28a03afa77",
            "type": "main",
            "index": 0
          },
          {
            "node": "3eb9a6d5-3e1a-4761-aafe-4ec1c7fcf028",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d0af1ffb-9b14-47d6-b0fa-74828c16398b": {
      "main": [
        [
          {
            "node": "eeff26db-3267-4126-81e1-df6996106aaf",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "65d92503-fad1-4816-88d4-9f28a03afa77": {
      "main": [
        [
          {
            "node": "3eb9a6d5-3e1a-4761-aafe-4ec1c7fcf028",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "c64f155a-bdcc-46c2-a47e-6a14998a0752": {
      "ai_languageModel": [
        [
          {
            "node": "fedb0008-1164-4c8c-b699-a4576ccb3f14",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "c038c2ed-74c0-4ab7-8377-564c4bb7d6db": {
      "main": [
        [
          {
            "node": "487e1170-ed55-4273-93b0-38df2dc73452",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "0bf75f31-39e1-4011-837d-6da8bd431c04": {
      "main": [
        [
          {
            "node": "e34867e7-8e27-4a2a-93be-8a67ed646e22",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "eeff26db-3267-4126-81e1-df6996106aaf": {
      "main": [
        [
          {
            "node": "4ad67f5f-8a7d-4d70-9c3e-a3d250c2562d",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8b59e674-859c-462f-b8b2-dea794351f28": {
      "ai_outputParser": [
        [
          {
            "node": "fedb0008-1164-4c8c-b699-a4576ccb3f14",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "e34867e7-8e27-4a2a-93be-8a67ed646e22": {
      "main": [
        [
          {
            "node": "c038c2ed-74c0-4ab7-8377-564c4bb7d6db",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5f7a1fd8-4935-4447-9a78-ddee0be57542": {
      "ai_tool": [
        [
          {
            "node": "fedb0008-1164-4c8c-b699-a4576ccb3f14",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "487e1170-ed55-4273-93b0-38df2dc73452": {
      "main": [
        [
          {
            "node": "fedb0008-1164-4c8c-b699-a4576ccb3f14",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Preguntas frecuentes

¿Cómo usar este flujo de trabajo?

Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.

¿En qué escenarios es adecuado este flujo de trabajo?

Avanzado - Recursos Humanos, Resumen de IA

¿Es de pago?

Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.

Información del flujo de trabajo
Nivel de dificultad
Avanzado
Número de nodos26
Categoría2
Tipos de nodos12
Descripción de la dificultad

Adecuado para usuarios avanzados, flujos de trabajo complejos con 16+ nodos

Autor
Gabriel Santos

Gabriel Santos

@gabrielhmsantos

Enthusiastic developer passionate about automation and system integration. I work mainly with Python, RPA, and N8N, building workflows and custom solutions to optimize processes and connect platforms. Always learning, sharing, and exploring new ways to automate smarter.

Enlaces externos
Ver en n8n.io

Compartir este flujo de trabajo

Categorías

Categorías: 34