AutomationFlowsAI & RAG › Automate Hr Q&a Sessions with AI Question Clustering and Google Calendar…

Automate Hr Q&a Sessions with AI Question Clustering and Google Calendar…

Original n8n title: Automate Hr Q&a Sessions with AI Question Clustering and Google Calendar Integration

ByGabriel Santos @gabrielhmsantos on n8n.io

This workflow helps HR teams run smoother monthly Q\&A sessions with employees.

Event trigger★★★★☆ complexityAI-powered26 nodesAgentGoogle Calendar ToolOpenAI ChatOutput Parser StructuredForm TriggerMySQLForm
AI & RAG Trigger: Event Nodes: 26 Complexity: ★★★★☆ AI nodes: yes Added:
Automate Hr Q&a Sessions with AI Question Clustering and Google Calendar… — n8n workflow card showing Agent, Google Calendar Tool, OpenAI Chat integration

This workflow corresponds to n8n.io template #8657 — we link there as the canonical source.

This workflow follows the Agent → Form recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "1VM3ArDydbQVPrdN",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Monthly HR Q&A in Google Meet",
  "tags": [],
  "nodes": [
    {
      "id": "fedb0008-1164-4c8c-b699-a4576ccb3f14",
      "name": "AI Agent",
      "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\u2019 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\u00e7\u00e3o\",\n    \"email\": \"gabriel.hmedeirossantos@gmail.com\",\n    \"question\": \"Como \u00e9 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\u201317:00, America/Sao_Paulo) before returning the final JSON.\n- The tool must be called with:\n  - `title`: \"Monthly HR Q&A \u2013 {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 \u2013 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 \u2013 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": "Create an event in 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": "user@example.com",
          "cachedResultName": "user@example.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": {
          "name": "<your credential>"
        }
      },
      "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": {
          "name": "<your credential>"
        }
      },
      "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 \u2013 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 \u2013 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": "Question form",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -208,
        -144
      ],
      "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., \u201cClear form\u201d) */\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 / \u201cAutomated with n8n\u201d ===== */\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": "Add question to database",
      "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": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.5
    },
    {
      "id": "4ad67f5f-8a7d-4d70-9c3e-a3d250c2562d",
      "name": "Return form",
      "type": "n8n-nodes-base.form",
      "position": [
        624,
        -144
      ],
      "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., \u201cClear form\u201d) */\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 / \u201cAutomated with n8n\u201d ===== */\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": "Form to get questions",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -208,
        288
      ],
      "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., \u201cClear form\u201d) */\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 / \u201cAutomated with n8n\u201d ===== */\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": "Get queries from the database",
      "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": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.5
    },
    {
      "id": "28a3be94-52e4-47d1-a37d-b43edb42a0c0",
      "name": "Return meeting script",
      "type": "n8n-nodes-base.form",
      "position": [
        2992,
        304
      ],
      "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., \u201cClear form\u201d) */\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 / \u201cAutomated with n8n\u201d ===== */\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": "Get start_date and end_date Meeting",
      "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    // \u00faltimo dia do m\u00eas\n    const lastDay = new Date(year, month + 1, 0);\n\n    // voltar at\u00e9 encontrar sexta (5)\n    while (lastDay.getDay() !== 5) {\n      lastDay.setDate(lastDay.getDate() - 1);\n    }\n\n    // definir hora da reuni\u00e3o (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\u00e1rio 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": "Aggregate Questions",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        624,
        288
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData",
        "destinationFieldName": "questions"
      },
      "typeVersion": 1
    },
    {
      "id": "ecacc9e8-a321-496e-b103-f66e3e48a0f8",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -320,
        -832
      ],
      "parameters": {
        "color": 4,
        "width": 848,
        "height": 448,
        "content": "## Monthly HR Q&A \u2014 End-to-end flow\n\nThis template collects employees\u2019 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": "Sticky Note1",
      "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 \u2192 forwards to DB insert node.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "d15210c2-8094-4220-a097-5621639df4bd",
      "name": "Sticky Note2",
      "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": "Sticky Note3",
      "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": "Sticky Note4",
      "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\" \u2192 start date\n- \"Until the day\" \u2192 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": "Sticky Note5",
      "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": "Sticky Note6",
      "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": "Sticky Note7",
      "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\u201317: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": "Sticky Note8",
      "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 \u2013 {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) \u2014 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": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2064,
        64
      ],
      "parameters": {
        "width": 368,
        "height": 400,
        "content": "Converts `output.script` (text) \u2192 MeetingItinerary.txt\n\nThis file is automatically downloaded in the final step.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "72b7e6ce-3b32-46a6-ada6-bcfc7a0f8b08",
      "name": "Sticky Note10",
      "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": "Sticky Note11",
      "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,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "7e3a6fd2-a3ee-435f-b4fe-d74dc6ee2203",
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "Return meeting script",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Convert to File",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Question form": {
      "main": [
        [
          {
            "node": "Add question to database",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert to File": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Questions": {
      "main": [
        [
          {
            "node": "Get start_date and end_date Meeting",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Form to get questions": {
      "main": [
        [
          {
            "node": "Get queries from the database",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add question to database": {
      "main": [
        [
          {
            "node": "Return form",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "AI Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Get queries from the database": {
      "main": [
        [
          {
            "node": "Aggregate Questions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create an event in Google Calendar": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Get start_date and end_date Meeting": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow helps HR teams run smoother monthly Q\&A sessions with employees.

Source: https://n8n.io/workflows/8657/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

HR Job Posting and Evaluation with AI. Uses formTrigger, airtable, googleDrive, stickyNote. Event-driven trigger; 36 nodes.

Form Trigger, Airtable, Google Drive +8
AI & RAG

HR Job Posting and Evaluation with AI. Uses formTrigger, airtable, googleDrive, stickyNote. Event-driven trigger; 36 nodes.

Form Trigger, Airtable, Google Drive +8
AI & RAG

The HR Job Posting and Evaluation with AI workflow is designed to streamline and enhance recruitment for technical roles, such as Automation Specialists. By automating key stages in the hiring process

Form Trigger, Airtable, Google Drive +8
AI & RAG

This workflow serves as a comprehensive "Workflow Nodes SEO & Documentation Generator". It uses AI to analyze, rename, and document n8n workflows, offering a streamlined way to optimize workflow reada

Form Trigger, n8n, Output Parser Autofixing +11
AI & RAG

This workflow streamlines how employees request equipment/items and how those requests reach the Procurement team. It validates the employee by enrollment number, detects whether a manager exists, and

Form Trigger, Form, OpenAI Chat +4