AutomationFlowsAI & RAG › Build an Openai Hr Assistant for Telegram Attendance and Salary Reports

Build an Openai Hr Assistant for Telegram Attendance and Salary Reports

Bykhaled yasser @khaledyasser01 on n8n.io

HR managers waste hours manually logging attendance, calculating work hours, and tracking salary advances in spreadsheets. Onboarding new staff often involves messy paperwork or scattered chat messages. Salary calculations are prone to errors when manually tallying absence,…

Event trigger★★★★★ complexityAI-powered47 nodesTelegram TriggerMemory Buffer WindowTelegramGoogle SheetsAgentOpenAI ChatGoogle Gemini Chat
AI & RAG Trigger: Event Nodes: 47 Complexity: ★★★★★ AI nodes: yes Added:
Build an Openai Hr Assistant for Telegram Attendance and Salary Reports — n8n workflow card showing Telegram Trigger, Memory Buffer Window, Telegram integration

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

This workflow follows the Agent → Google Sheets 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": "template-id",
  "name": "Manage employee onboarding and attendance using Telegram and OpenAI",
  "tags": [],
  "nodes": [
    {
      "id": "bd1",
      "name": "Main_Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2600,
        800
      ],
      "parameters": {
        "color": 1,
        "width": 386,
        "height": 516,
        "content": "### \ud83e\udd16 HR Automated System\n\n#### How it works\n1. **Input:** Receives Telegram messages from employees.\n2. **AI Analysis:** Classifies intent (Attendance, Report, or Registration) using OpenAI.\n3. **Execution:** \n   - Logs Check-in/out & calculates penalties for early departure.\n   - Registers new employees via chat conversation.\n   - Generates salary reports based on attendance history.\n4. **Automation:** Runs a daily scheduled job to report absentees.\n\n#### Setup steps\n1. **Credentials:** Connect your Telegram Bot, OpenAI, and Google Sheets accounts.\n2. **Google Sheet:** Create a sheet with columns: `[Name, ID, Role, Branch, Salary]` and a second tab for `Logs`.\n3. **IDs:** Replace `[YOUR_SPREADSHEET_ID]` in all Sheet nodes.\n4. **Timezone:** Adjust the `Context` in the AI Agent nodes to your local timezone."
      },
      "typeVersion": 1
    },
    {
      "id": "bd2",
      "name": "Section_Input",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2160,
        1040
      ],
      "parameters": {
        "color": 7,
        "width": 1900,
        "height": 560,
        "content": "## 1. Input & Intent Classification\nReceives messages, maintains chat history, and uses AI to determine if the user is a new employee, recording a transaction, or asking for a report."
      },
      "typeVersion": 1
    },
    {
      "id": "bd3",
      "name": "Section_Onboarding",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        100,
        -120
      ],
      "parameters": {
        "color": 7,
        "width": 2100,
        "height": 700,
        "content": "## 2. New Employee Onboarding\nHandles the conversational flow to register new staff. Collects Name, ID, Salary, etc., validates the JSON data, and saves to the database."
      },
      "typeVersion": 1
    },
    {
      "id": "bd4",
      "name": "Section_Transactions",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        400,
        640
      ],
      "parameters": {
        "color": 7,
        "width": 1700,
        "height": 950,
        "content": "## 3. Transaction Logic\nHandles existing employees. Logs Attendance, calculates 'Early Departure' penalties based on work hours, and records Salary Advances."
      },
      "typeVersion": 1
    },
    {
      "id": "bd5",
      "name": "Section_Reports",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        900,
        1720
      ],
      "parameters": {
        "color": 7,
        "width": 1200,
        "height": 450,
        "content": "## 4. Financial Reporting\nFetches employee salary and movement history to calculate net pay (deducting absence/penalties and adding overtime)."
      },
      "typeVersion": 1
    },
    {
      "id": "bd6",
      "name": "Section_Daily",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2160,
        1680
      ],
      "parameters": {
        "color": 7,
        "width": 2000,
        "height": 450,
        "content": "## 5. Daily Scheduled Jobs\nRuns automatically (e.g., at 1:00 PM) to compare today's logs against the full employee list and report who is absent."
      },
      "typeVersion": 1
    },
    {
      "id": "e91f272e-19ae-4903-bc5f-8b012419d324",
      "name": "Telegram_Trigger",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        -2112,
        1136
      ],
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "9d8e575c-f625-42c9-a16c-aa53e355cbf5",
      "name": "Memory_Chat",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        -992,
        1424
      ],
      "parameters": {
        "sessionKey": "chat_history",
        "sessionIdType": "customKey"
      },
      "typeVersion": 1.3
    },
    {
      "id": "343f675f-58ab-409e-b0f6-b965b80c308d",
      "name": "Msg_Attendance_Success",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1968,
        1488
      ],
      "parameters": {
        "text": "=\u2600\ufe0f Good morning, \n{{ $json['\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641'] }} \n\n\u2705 Your attendance has been successfully recorded!\n\u23f0 Arrival Time: \n{{ $json['\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u0648\u0627\u0644\u0648\u0642\u062a'] }}\n\nWishing you a productive and successful workday! \ud83d\udcaa\ud83d\ude80",
        "chatId": "={{ $('Telegram_Trigger').item.json.message.chat.id }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "c1c37e47-d9b8-4358-92c5-d62e194fb9c3",
      "name": "Parse_AI_Response",
      "type": "n8n-nodes-base.code",
      "position": [
        -624,
        1200
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// 1. Safely receive text (whether named output or text)\nconst aiResponse = $json.output || $json.text;\n\n// 2. Safety check: If no data, stop and output a clear error message\nif (!aiResponse) {\n  throw new Error(\"Alert: No response received from AI (variable is empty).\");\n}\n\n// 3. Clean text from Markdown tags (```json)\nconst cleanJson = aiResponse.replace(/```json/g, '').replace(/```/g, '').trim();\n\n// 4. Convert text to JSON object and return\nreturn JSON.parse(cleanJson);"
      },
      "typeVersion": 2
    },
    {
      "id": "05d87ded-fb5b-499e-95fe-43e0f013a877",
      "name": "Lookup_Employee",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -80,
        1120
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ $json.identifier }}",
              "lookupColumn": "\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641"
            },
            {
              "lookupValue": "={{ $json.identifier }}",
              "lookupColumn": "\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "[https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)[YOUR_SPREADSHEET_ID]/edit#gid=0",
          "cachedResultName": "data"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "[YOUR_SPREADSHEET_ID]",
          "cachedResultUrl": "[https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)[YOUR_SPREADSHEET_ID]",
          "cachedResultName": "[YOUR_SHEET_NAME]"
        },
        "combineFilters": "OR"
      },
      "typeVersion": 4.7,
      "alwaysOutputData": true
    },
    {
      "id": "8905ab06-d258-404c-b9d3-ee60ef5a29ce",
      "name": "Log_Transaction",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1440,
        1488
      ],
      "parameters": {
        "columns": {
          "value": {
            "\u0627\u0644\u0642\u064a\u0645\u0647": "={{ $('Parse_AI_Response').item.json.value }}",
            "\u0645\u0644\u0627\u062d\u0627\u0638\u0627\u062a": "={{ $('Parse_AI_Response').item.json.notes }}",
            "\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641": "={{ $('Lookup_Employee').item.json['\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641'] }}",
            "\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641": "={{ $json['\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641'] }}",
            "\u0646\u0648\u0639 \u0627\u0644\u062d\u0631\u0643\u0647": "={{ $('Parse_AI_Response').item.json.action }}",
            "\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u0648\u0627\u0644\u0648\u0642\u062a": "={{ $('Parse_AI_Response').item.json.timestamp }}"
          },
          "schema": [
            {
              "id": "\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u0648\u0627\u0644\u0648\u0642\u062a",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u0648\u0627\u0644\u0648\u0642\u062a",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0646\u0648\u0639 \u0627\u0644\u062d\u0631\u0643\u0647",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0646\u0648\u0639 \u0627\u0644\u062d\u0631\u0643\u0647",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0627\u0644\u0642\u064a\u0645\u0647",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0627\u0644\u0642\u064a\u0645\u0647",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0645\u0644\u0627\u062d\u0627\u0638\u0627\u062a",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0645\u0644\u0627\u062d\u0627\u0638\u0627\u062a",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "[YOUR_LOGS_SHEET_GID]",
          "cachedResultUrl": "[https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)[YOUR_SPREADSHEET_ID]/edit#gid=[YOUR_LOGS_SHEET_GID]",
          "cachedResultName": "\u0633\u062c\u0644 \u0627\u0644\u062d\u0631\u0643\u0627\u062a"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "[YOUR_SPREADSHEET_ID]",
          "cachedResultUrl": "[https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)[YOUR_SPREADSHEET_ID]",
          "cachedResultName": "[YOUR_SHEET_NAME]"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "922eae56-0829-4191-9998-6887c5c85a85",
      "name": "Check_Employee_Found",
      "type": "n8n-nodes-base.if",
      "position": [
        144,
        1120
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "6d680a3d-c8ba-40b7-913e-02962e7fb6dd",
              "operator": {
                "type": "number",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json['\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641'] }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "c15a466a-1e19-427a-9e66-013a45a139de",
      "name": "Msg_Employee_Not_Found",
      "type": "n8n-nodes-base.telegram",
      "position": [
        320,
        1200
      ],
      "parameters": {
        "text": "=Sorry, this code ({{ $('Route_Intent').item.json.identifier }}) is not registered in our system! \ud83e\udd14\n\nIf this is a new employee, reply with \"Yes\" to add them.\nIf there's a mistake, please double-check the code and try again.\n\nFor assistance, contact KHALED YASSER \ud83d\udcde",
        "chatId": "={{ $('Telegram_Trigger').item.json.message.chat.id }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "1007f64f-4269-4558-9cee-a7cf6d57050c",
      "name": "Route_Intent",
      "type": "n8n-nodes-base.switch",
      "onError": "continueRegularOutput",
      "position": [
        -400,
        1200
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "cd801203-7ecb-44fd-b60d-ff5f076e609e",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.intent }}",
                    "rightValue": "record"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "295bdf3d-531b-46c9-9592-bca673a1d0a4",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.intent }}",
                    "rightValue": "report"
                  }
                ]
              }
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.4
    },
    {
      "id": "cd13e552-f0bb-4097-96c6-431cefc5f086",
      "name": "Memory_Analyst",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        1696,
        2080
      ],
      "parameters": {
        "sessionKey": "chat_history",
        "sessionIdType": "customKey"
      },
      "typeVersion": 1.3
    },
    {
      "id": "bcc064a5-7e14-40cb-8948-1a03785c1c53",
      "name": "Msg_Analysis_Report",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1984,
        1808
      ],
      "parameters": {
        "text": "={{ $json.output }}",
        "chatId": "={{ $('Telegram_Trigger').item.json.message.chat.id }}",
        "additionalFields": {
          "parse_mode": "HTML",
          "appendAttribution": false
        }
      },
      "executeOnce": true,
      "typeVersion": 1.2
    },
    {
      "id": "930fd357-49f1-49f4-b70a-d46360b31b95",
      "name": "Agent_Classifier",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "onError": "continueRegularOutput",
      "position": [
        -1120,
        1184
      ],
      "parameters": {
        "text": "={{ $json.message.text }}",
        "options": {
          "systemMessage": "==# Role: HR Data Extractor & Router\n# Objective: Analyze the user's message to determine the intent (Recording Transaction OR Requesting Report) and extract relevant data strictly as JSON.\n\n# Context:\nThe exact current date and time in Africa/Cairo is: ={{ $now.setZone('Africa/Cairo').toFormat('yyyy-MM-dd hh:mm:ss a') }}\n\n# Instructions:\nAnalyze the user's message (English or Arabic) and output a JSON object with these exact fields:\n\n1. \"intent\": Determine the user's goal. MUST be one of:\n   - \"record\": If user wants to log attendance, absence, money, etc. (e.g., \"\u062d\u0636\u0648\u0631 1001\", \"Advance 500\").\n   - \"report\": If user asks for info or summary (e.g., \"Report for Fatima\", \"How many days was Mohamed absent?\").\n\n2. \"action\": \n   - If intent is \"record\": Extract the action type EXACTLY as one of these Arabic terms to match the database: (\u062d\u0636\u0648\u0631, \u0627\u0646\u0635\u0631\u0627\u0641, \u063a\u064a\u0627\u0628, \u0646\u0635 \u064a\u0648\u0645, \u0633\u0644\u0641, \u0627\u0636\u0627\u0641\u064a, \u0627\u062c\u0627\u0632\u0647).\n   - If intent is \"report\": Output \"report\".\n\n3. \"identifier\": The Employee ID or Name mentioned.\n4. \"value\": Amount or hours (if applicable), otherwise null.\n5. \"notes\": Any extra details.\n6. \"timestamp\": Current time from Context.\n\n# Output Format:\nYou MUST output ONLY a valid JSON object. Do NOT wrap in markdown blocks.\n\n# Example 1 (Recording):\nUser: \"Clock-in 1001\"\nOutput: { \"intent\": \"record\", \"action\": \"\u062d\u0636\u0648\u0631\", \"identifier\": \"1001\", \"value\": null, \"notes\": \"\", \"timestamp\": \"...\" }\n\n# Example 2 (Reporting):\nUser: \"Report for Fatima Rouge\"\nOutput: { \"intent\": \"report\", \"action\": \"report\", \"identifier\": \"Fatima Rouge\", \"value\": null, \"notes\": \"\", \"timestamp\": \"...\" }"
        },
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "51a67c9b-73e9-44ac-9c77-bdbf56ee9aff",
      "name": "Agent_Financial",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "onError": "continueRegularOutput",
      "position": [
        1552,
        1808
      ],
      "parameters": {
        "text": "=Employee Basic Salary: {{ $('Fetch_Salary').item.json['\u0627\u0644\u0631\u0627\u062a\u0628 \u0627\u0644\u0627\u0633\u0627\u0633\u064a'] }}\nMovements Log: {{ JSON.stringify($input.all().map(item => item.json)) }}",
        "options": {
          "systemMessage": "=Role: Professional HR Financial Analyst (XQ Pharma)\nObjective: Calculate the Net Salary strictly following the company's rules.\n\n# Input Data:\n1. Basic Salary.\n2. Movement Logs (Absence, Overtime, Advances, Departures, etc.).\n\n# Financial Rules (As per company policy):\n- Day Value = (Basic Salary / 30).\n- \"\u063a\u064a\u0627\u0628\" (Absence): Deduct 1 full Day Value (-1.0).\n- \"\u0627\u0636\u0627\u0641\u064a\" (Overtime): Add 1 full Day Value (+1.0).\n- \"\u0633\u0644\u0641\" (Advances): Deduct the exact amount provided in the \"value\" field.\n- \"\u0627\u0646\u0635\u0631\u0627\u0641\" (Departure): If marked as \"Early Departure\" or \"Penalty\", deduct 0.25 of a Day Value.\n- \"\u0627\u062c\u0627\u0632\u0647\" (Leaves): No deduction (Sick, Annual, Official holidays are paid).\n\n# Calculation Logic:\n- Calculate Total Deductions (Absence + Advances + Early Departure Penalties).\n- Calculate Total Additions (Overtime).\n- Net Salary = Basic Salary + Additions - Deductions.\n\n# Final Report (English):\nFinancial Report for Employee: [Name] (ID: [ID])\n--------------------------------------------------\n\ud83d\udcb0 Basic Salary: [Salary] EGP\n\ud83d\udcca Day Value: [Day Value] EGP\n\n\ud83d\udd3b Deductions:\n- Absence ([X] days): -[Value] EGP\n- Advances: -[Value] EGP\n- Early Departure Penalties: -[Value] EGP\n\n\u2705 Additions & Dues:\n- Overtime ([X] days): +[Value] EGP\n\n\ud83d\udcb5 Net Salary Due: [Net Salary] EGP\n--------------------------------------------------\nBest regards,\nKHALED YASSER"
        },
        "promptType": "define"
      },
      "retryOnFail": true,
      "typeVersion": 3.1
    },
    {
      "id": "28d59d05-42ae-4325-aa42-edfda12a4da3",
      "name": "Msg_Ask_New_Emp_Data",
      "type": "n8n-nodes-base.telegram",
      "position": [
        208,
        -64
      ],
      "parameters": {
        "text": "=\ud83c\udf89 Welcome to the XQ Pharma team! \ud83e\udd1d\n\nTo successfully register your details in the company's system, please send the following information in a single line, separated by dashes (-):\n\n(Code - Name - Position - Branch - Salary) \ud83d\udcdd\n\n\ud83d\udca1 Example:\n1005 - Mohamed Ahmed - Sales - Maadi - 6000\n\nAwaiting your details so we can get started! \ud83d\ude80\u2728",
        "chatId": "={{ $('Telegram_Trigger').item.json.message.chat.id }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "83bce609-761a-46e0-9d87-dd17fdec2e1e",
      "name": "Memory_Onboarding",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        992,
        528
      ],
      "parameters": {
        "sessionKey": "chat_history",
        "sessionIdType": "customKey"
      },
      "typeVersion": 1.3
    },
    {
      "id": "7d49dd78-9d34-40cb-b865-dab0bb81e9bf",
      "name": "Agent_Onboarding",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        928,
        288
      ],
      "parameters": {
        "text": "={{ $('Telegram_Trigger').item.json.message.text }}",
        "options": {
          "systemMessage": "Role: Professional HR Assistant\nObjective: Capture new employee details and register them.\n\nCRITICAL LOGIC:\n\nIf the user says \"Yes\" without providing details:\n\nDO NOT use the registration tool/node.\n\nDO NOT output any JSON or structured data.\n\nReply ONLY with the \"Mandatory Response Format\" below.\n\nIf and only if the message contains real data (like a name and a code):\n\nExtract the data and proceed to register the employee using the tool.\n\nMandatory Response Format for \"Yes\" or missing data:\n\"Great! To register the employee, please send the following details in a single message in this order: (Employee Code - Name - Position - Branch - Salary)\"\n\nMandatory Closing:\nBest regards,\nKHALED YASSER"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "08e69c55-7eca-445e-9cc5-b48d926930cb",
      "name": "Validate_New_Emp_JSON",
      "type": "n8n-nodes-base.code",
      "position": [
        1280,
        288
      ],
      "parameters": {
        "jsCode": "// 1. Receive output from the Agent\nconst rawOutput = $input.all()[0].json.output;\n\ntry {\n  // 2. Search for JSON (employee data) inside the text\n  const jsonMatch = rawOutput.match(/\\{[\\s\\S]*\\}/);\n\n  if (jsonMatch) {\n    // If data is found, parse it and pass it through\n    const cleanJson = JSON.parse(jsonMatch[0]);\n    return [{ json: { ...cleanJson, is_valid: true } }];\n  } else {\n    // If it's a regular message, send false to close the route smoothly\n    return [{ json: { is_valid: false } }];\n  }\n} catch (e) {\n  // In case of any error, close the route without stopping the workflow\n  return [{ json: { is_valid: false } }];\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "4ebe2121-1ad1-47bd-b187-c625871218ea",
      "name": "Register_New_Emp",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1744,
        288
      ],
      "parameters": {
        "columns": {
          "value": {
            "\u0627\u0644\u0641\u0631\u0639": "={{ $json.branch }}",
            "\u0627\u0644\u0648\u0638\u064a\u0641\u0647": "={{ $json.position }}",
            "\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641": "={{ $json.name }}",
            "\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641": "={{ $json.code }}",
            "\u0627\u0644\u0631\u0627\u062a\u0628 \u0627\u0644\u0627\u0633\u0627\u0633\u064a": "={{ $json.salary }}"
          },
          "schema": [
            {
              "id": "\u0645",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0645",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0627\u0644\u0648\u0638\u064a\u0641\u0647",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0627\u0644\u0648\u0638\u064a\u0641\u0647",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0627\u0644\u0641\u0631\u0639",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0627\u0644\u0641\u0631\u0639",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0627\u0644\u0631\u0627\u062a\u0628 \u0627\u0644\u0627\u0633\u0627\u0633\u064a",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0627\u0644\u0631\u0627\u062a\u0628 \u0627\u0644\u0627\u0633\u0627\u0633\u064a",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0627\u0644\u062d\u0627\u0644\u0647",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0627\u0644\u062d\u0627\u0644\u0647",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "[https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)[YOUR_SPREADSHEET_ID]/edit#gid=0",
          "cachedResultName": "data"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "[YOUR_SPREADSHEET_ID]",
          "cachedResultUrl": "[https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)[YOUR_SPREADSHEET_ID]",
          "cachedResultName": "[YOUR_SHEET_NAME]"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "183fbd9c-8ff9-44ac-9b48-e1b07b739896",
      "name": "Msg_Registration_Success",
      "type": "n8n-nodes-base.telegram",
      "position": [
        2048,
        288
      ],
      "parameters": {
        "text": "=\"\u2705 Employee successfully registered!\n\ud83d\udc64 Name: {{ $json['\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641'] }}\n\ud83c\udd94 Code: {{ $json['\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641'] }}\n\ud83c\udfe2 Branch: {{ $json['\u0627\u0644\u0641\u0631\u0639'] }}\n\ud83d\udee0\ufe0f Position: {{ $json['\u0627\u0644\u0648\u0638\u064a\u0641\u0647'] }}\n\ud83d\udcb0 Salary: {{ $json['\u0627\u0644\u0631\u0627\u062a\u0628 \u0627\u0644\u0627\u0633\u0627\u0633\u064a'] }}\"\n\nBest regards, \nKHALED YASSER",
        "chatId": "={{ $('Telegram_Trigger').item.json.message.chat.id }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "4c353579-e15a-4ee6-9736-bd074627c258",
      "name": "Model_Onboarding",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        832,
        528
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "typeVersion": 1.3
    },
    {
      "id": "b34e24ea-45f1-4321-9ee0-3823dae1d2d1",
      "name": "Model_Classifier",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -1152,
        1408
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "typeVersion": 1.3
    },
    {
      "id": "e281d6a4-1f02-4d1a-8f16-adddc01a7b6a",
      "name": "Model_Analyst",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1504,
        2080
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "typeVersion": 1.3
    },
    {
      "id": "ef84526d-6f92-44c7-b73e-cff9618c614b",
      "name": "Filter_Valid_Data",
      "type": "n8n-nodes-base.filter",
      "position": [
        1488,
        288
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "13adeb08-47d8-48f4-be4d-ce8a5a33ccd3",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.is_valid }}",
              "rightValue": false
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "77d625e6-045d-45f7-8ad2-612a47cacec4",
      "name": "Route_New_vs_Existing",
      "type": "n8n-nodes-base.switch",
      "position": [
        -1840,
        1120
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "94182e02-dff7-4cc3-b312-45476c9a91ea",
                    "operator": {
                      "type": "string",
                      "operation": "contains"
                    },
                    "leftValue": "={{ $json.message.text }}",
                    "rightValue": "Yes"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "538a2b1c-743f-4f97-a79e-ac1833409841",
                    "operator": {
                      "type": "string",
                      "operation": "contains"
                    },
                    "leftValue": "={{ $json.message.text }}",
                    "rightValue": "Salary"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "e2dbe368-6edd-4b23-996d-e954ec60924e",
                    "operator": {
                      "type": "string",
                      "operation": "contains"
                    },
                    "leftValue": "={{ $json.message.text }}",
                    "rightValue": "-"
                  }
                ]
              }
            }
          ]
        },
        "options": {
          "fallbackOutput": 2
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "04cf0510-c901-4cce-ac4f-67a80a735b00",
      "name": "Fetch_Salary",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1024,
        1808
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ $json.identifier }}",
              "lookupColumn": "\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "[https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)[YOUR_SPREADSHEET_ID]/edit#gid=0",
          "cachedResultName": "data"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "[YOUR_SPREADSHEET_ID]",
          "cachedResultUrl": "[https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)[YOUR_SPREADSHEET_ID]",
          "cachedResultName": "[YOUR_SHEET_NAME]"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "a80dfc13-348d-4bf4-99f9-b5a3e28ebe62",
      "name": "Fetch_Movement_History",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1312,
        1808
      ],
      "parameters": {
        "options": {
          "returnFirstMatch": false
        },
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ $('Parse_AI_Response').item.json.identifier }}",
              "lookupColumn": "\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "[YOUR_LOGS_SHEET_GID]",
          "cachedResultUrl": "[https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)[YOUR_SPREADSHEET_ID]/edit#gid=[YOUR_LOGS_SHEET_GID]",
          "cachedResultName": "\u0633\u062c\u0644 \u0627\u0644\u062d\u0631\u0643\u0627\u062a"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "[YOUR_SPREADSHEET_ID]",
          "cachedResultUrl": "[https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)[YOUR_SPREADSHEET_ID]",
          "cachedResultName": "[YOUR_SHEET_NAME]"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "fbdfb942-abec-4873-8d96-ce9d19e8a267",
      "name": "Model_Gemini",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -1328,
        1408
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "1f589c8f-e9dd-4457-9f8f-30eda9b24703",
      "name": "Route_Action_Type",
      "type": "n8n-nodes-base.switch",
      "position": [
        512,
        1088
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "58b9b9c0-0507-4559-85ea-99709b2d03bf",
                    "operator": {
                      "type": "string",
                      "operation": "contains"
                    },
                    "leftValue": "={{ $('Parse_AI_Response').item.json.action }}",
                    "rightValue": "\u0627\u0646\u0635\u0631\u0627\u0641"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "dba0f0db-16e5-431e-9ffb-6d0990d7e643",
                    "operator": {
                      "type": "string",
                      "operation": "contains"
                    },
                    "leftValue": "={{ $('Parse_AI_Response').item.json.action }}",
                    "rightValue": "\u0633\u0644\u0641"
                  }
                ]
              }
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "6b9d65db-09a9-4a82-b726-432d7807904b",
      "name": "Calc_Departure_Stats",
      "type": "n8n-nodes-base.code",
      "position": [
        1456,
        784
      ],
      "parameters": {
        "jsCode": "// 1. Get attendance time from the previous node\nconst attendanceStr = $('Get_Arrival_Time').item.json['\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u0648\u0627\u0644\u0648\u0642\u062a'];\nconst attendanceTime = new Date(attendanceStr);\n\n// 2. Get current departure time\nconst departureTime = new Date($('Parse_AI_Response').item.json.timestamp);\n\n// 3. Calculate time difference\nconst diffInMs = departureTime - attendanceTime;\nconst diffInHours = diffInMs / (1000 * 60 * 60);\n\n// 4. Apply 8-hour rule\nlet penaltyNotes = \"Normal departure\";\nlet isPenalty = false;\n\nif (diffInHours < 8) {\n    penaltyNotes = `Early departure (worked only ${diffInHours.toFixed(2)} hours)`;\n    isPenalty = true;\n}\n\nreturn {\n    attendance_time: attendanceStr,\n    departure_time: departureTime.toLocaleString(),\n    hours_worked: diffInHours.toFixed(2),\n    is_early_departure: isPenalty,\n    notes: penaltyNotes\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "e25a56b9-b576-442a-bffa-7726d6db78ed",
      "name": "Get_Arrival_Time",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1200,
        784
      ],
      "parameters": {
        "options": {
          "returnFirstMatch": true
        },
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ $('Parse_AI_Response').item.json.identifier }}",
              "lookupColumn": "\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641"
            },
            {
              "lookupValue": "\u062d\u0636\u0648\u0631",
              "lookupColumn": "\u0646\u0648\u0639 \u0627\u0644\u062d\u0631\u0643\u0647"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "[YOUR_LOGS_SHEET_GID]",
          "cachedResultUrl": "[https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)[YOUR_SPREADSHEET_ID]/edit#gid=[YOUR_LOGS_SHEET_GID]",
          "cachedResultName": "\u0633\u062c\u0644 \u0627\u0644\u062d\u0631\u0643\u0627\u062a"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "[YOUR_SPREADSHEET_ID]",
          "cachedResultUrl": "[https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)[YOUR_SPREADSHEET_ID]",
          "cachedResultName": "[YOUR_SHEET_NAME]"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "8ceb01d2-bc69-448b-854d-ffb0d4142099",
      "name": "Log_Departure",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1728,
        784
      ],
      "parameters": {
        "columns": {
          "value": {
            "\u0645\u0644\u0627\u062d\u0627\u0638\u0627\u062a": "={{ $json.notes }}",
            "\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641": "={{ $('Get_Arrival_Time').item.json['\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641'] }}",
            "\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641": "={{ $('Parse_AI_Response').item.json.identifier }}",
            "\u0646\u0648\u0639 \u0627\u0644\u062d\u0631\u0643\u0647": "\u0627\u0646\u0635\u0631\u0627\u0641",
            "\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u0648\u0627\u0644\u0648\u0642\u062a": "={{ $json.departure_time }}"
          },
          "schema": [
            {
              "id": "\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u0648\u0627\u0644\u0648\u0642\u062a",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u0648\u0627\u0644\u0648\u0642\u062a",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0646\u0648\u0639 \u0627\u0644\u062d\u0631\u0643\u0647",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0646\u0648\u0639 \u0627\u0644\u062d\u0631\u0643\u0647",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0627\u0644\u0642\u064a\u0645\u0647",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0627\u0644\u0642\u064a\u0645\u0647",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0645\u0644\u0627\u062d\u0627\u0638\u0627\u062a",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0645\u0644\u0627\u062d\u0627\u0638\u0627\u062a",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "[YOUR_LOGS_SHEET_GID]",
          "cachedResultUrl": "[https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)[YOUR_SPREADSHEET_ID]/edit#gid=[YOUR_LOGS_SHEET_GID]",
          "cachedResultName": "\u0633\u062c\u0644 \u0627\u0644\u062d\u0631\u0643\u0627\u062a"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "[YOUR_SPREADSHEET_ID]",
          "cachedResultUrl": "[https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)[YOUR_SPREADSHEET_ID]",
          "cachedResultName": "[YOUR_SHEET_NAME]"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "3d60b776-91ee-4568-9c23-3c12a65a7c5d",
      "name": "Msg_Departure_Success",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1984,
        784
      ],
      "parameters": {
        "text": "=\ud83d\udc4b Great job, \n{{ $json['\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641'] }}!\n\n\u2705 Your clock-out has been recorded.\n\u23f1\ufe0f Hours worked:\n{{ $('Calc_Departure_Stats').item.json.hours_worked }}\n\ud83d\udcdd Note:\n{{ $('Calc_Departure_Stats').item.json.notes }}\n\nRest up and recharge for tomorrow. Have a good night! \ud83c\udfe0\u2728",
        "chatId": "={{ $('Telegram_Trigger').item.json.message.chat.id }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "1537466e-940c-4788-8966-c0019d116a38",
      "name": "Msg_Advance_Success",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1968,
        1104
      ],
      "parameters": {
        "text": "=\ud83d\udcb8 Financial Notice: {{ $json['\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641'] }}\n\nYour \"Advance\" request has been successfully recorded \u2705\n\ud83d\udcb0 Amount: {{ $json['\u0627\u0644\u0642\u064a\u0645\u0647'] }} EGP\n\ud83d\udcc5 Date: {{ $json['\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u0648\u0627\u0644\u0648\u0642\u062a'] }}\n\nThis will be reviewed and deducted from the current month's salary. Best of luck! \ud83d\udcbc\u2728",
        "chatId": "={{ $('Telegram_Trigger').item.json.message.chat.id }}",
        "additionalFields": {
          "appendAttribution": false
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "a5721408-c091-4591-95f4-d5a2c421ed78",
      "name": "Log_Advance",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1424,
        1104
      ],
      "parameters": {
        "columns": {
          "value": {
            "\u0627\u0644\u0642\u064a\u0645\u0647": "={{ $('Parse_AI_Response').item.json.value }}",
            "\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641": "={{ $('Lookup_Employee').item.json['\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641'] }}",
            "\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641": "={{ $('Lookup_Employee').item.json['\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641'] }}",
            "\u0646\u0648\u0639 \u0627\u0644\u062d\u0631\u0643\u0647": "={{ $('Parse_AI_Response').item.json.action }}",
            "\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u0648\u0627\u0644\u0648\u0642\u062a": "={{ $('Parse_AI_Response').item.json.timestamp }}"
          },
          "schema": [
            {
              "id": "\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u0648\u0627\u0644\u0648\u0642\u062a",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u0648\u0627\u0644\u0648\u0642\u062a",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0646\u0648\u0639 \u0627\u0644\u062d\u0631\u0643\u0647",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0646\u0648\u0639 \u0627\u0644\u062d\u0631\u0643\u0647",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0627\u0644\u0642\u064a\u0645\u0647",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0627\u0644\u0642\u064a\u0645\u0647",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "\u0645\u0644\u0627\u062d\u0627\u0638\u0627\u062a",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "\u0645\u0644\u0627\u062d\u0627\u0638\u0627\u062a",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "[YOUR_LOGS_SHEET_GID]",
          "cachedResultUrl": "[https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)[YOUR_SPREADSHEET_ID]/edit#gid=[YOUR_LOGS_SHEET_GID]",
          "cachedResultName": "\u0633\u062c\u0644 \u0627\u0644\u062d\u0631\u0643\u0627\u062a"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "[YOUR_SPREADSHEET_ID]",
          "cachedResultUrl": "[https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)[YOUR_SPREADSHEET_ID]",
          "cachedResultName": "[YOUR_SHEET_NAME]"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "bfce569a-1307-44b8-b0ec-bd011b2392c4",
      "name": "Daily_Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -2080,
        1904
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 13
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "5409f06a-f95d-43c7-830e-239ffb8ccf05",
      "name": "Filter_Today_Attendance",
      "type": "n8n-nodes-base.filter",
      "position": [
        -1200,
        1760
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "ea3a8847-35b5-4ecb-9e56-6fd741145e5f",
              "operator": {
                "type": "string",
                "operation": "startsWith"
              },
              "leftValue": "={{ $json['\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u0648\u0627\u0644\u0648\u0642\u062a'] }}",
              "rightValue": "={{ $now.format('yyyy-MM-dd') }}"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "2f455047-b858-44b8-89e2-a2f41d3200dc",
      "name": "Fetch_All_Employees",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1424,
        2048
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "[https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)[YOUR_SPREADSHEET_ID]/edit#gid=0",
          "cachedResultName": "data"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "[YOUR_SPREADSHEET_ID]",
          "cachedResultUrl": "[https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)[YOUR_SPREADSHEET_ID]",
          "cachedResultName": "[YOUR_SHEET_NAME]"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "2191b104-2953-41ee-ade4-9de610e35ad2",
      "name": "Fetch_Today_Logs",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1552,
        1744
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "\u062d\u0636\u0648\u0631",
              "lookupColumn": "\u0646\u0648\u0639 \u0627\u0644\u062d\u0631\u0643\u0647"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "[YOUR_LOGS_SHEET_GID]",
          "cachedResultUrl": "[https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)[YOUR_SPREADSHEET_ID]/edit#gid=[YOUR_LOGS_SHEET_GID]",
          "cachedResultName": "\u0633\u062c\u0644 \u0627\u0644\u062d\u0631\u0643\u0627\u062a"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "[YOUR_SPREADSHEET_ID]",
          "cachedResultUrl": "[https://docs.google.com/spreadsheets/d/](https://docs.google.com/spreadsheets/d/)[YOUR_SPREADSHEET_ID]",
          "cachedResultName": "[YOUR_SHEET_NAME]"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "c0a98dc7-a160-408c-abd5-b9ce5732284a",
      "name": "Calc_Absentees",
      "type": "n8n-nodes-base.code",
      "position": [
        -496,
        1904
      ],
      "parameters": {
        "jsCode": "const allEmployees = $items(\"Fetch_All_Employees\"); // Must exactly match node name \"Fetch_All_Employees\"\nconst todayAttendance = $items(\"Filter_Today_Attendance\"); // Must exactly match node name \"Filter_Today_Attendance\"\n\nconst attendedIds = todayAttendance.map(item => item.json[\"\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641\"]);\nconst absentees = allEmployees.filter(emp => !attendedIds.includes(emp.json[\"\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641\"]));\n\nreturn absentees;"
      },
      "typeVersion": 2
    },
    {
      "id": "05f58671-0c85-411a-b898-4296df21eed8",
      "name": "Msg_Absentee_Report",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -176,
        1904
      ],
      "parameters": {
        "text": "=\ud83d\udcca Daily Absence Report (1:00 PM) \ud83d\udcca\n-----------------------------------\n\ud83d\udccd Total Employees: {{ $items(\"Fetch_All_Employees\").length }}\n\u2705 Attendees: {{ new Set($items(\"Filter_Today_Attendance\").map(i => i.json[\"\u0643\u0648\u062f \u0627\u0644\u0645\u0648\u0638\u0641\"])).size }}\n\u274c Absentees: {{ $input.all().length }}\n-----------------------------------\n\u26a0\ufe0f List of Late/Absent Employees:\n{{ $input.all().map(item => \"\u2022 \" + item.json[\"\u0627\u0633\u0645 \u0627\u0644\u0645\u0648\u0638\u0641\"]).join('\\n') }}\n\nPlease follow up with them to ensure workflow continuity! \ud83d\ude80\u2728",
        "chatId": "=[ADMIN_CHAT_ID]",
        "additionalFields": {
          "parse_mode": "HTML",
          "appendAttribution": false
        }
      },
      "executeOnce": true,
      "typeVersion": 1.2
    },
    {
      "id": "2a47083b-fddf-4034-baaf-6489650aed3a",
      "name": "Merge_Lists",
      "type": "n8n-nodes-base.merge",
      "position": [
        -784,
        1904
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    }
  ],
  "active": false,
  "settings": {
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "template-version",
  "connections": {
    "Log_Advance": {
      "main": [
        [
          {
            "node": "Msg_Advance_Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Memory_Chat": {
      "ai_memory": [
        [
          {
            "node": "Agent_Classifier",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Merge_Lists": {
      "main": [
        [
          {
            "node": "Calc_Absentees",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch_Salary": {
      "main": [
        [
          {
            "node": "Fetch_Movement_History",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Model_Gemini": {
      "ai_languageModel": [
        []
      ]
    },
    "Route_Intent": {
      "main": [
        [
          {
            "node": "Lookup_Employee",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Fetch_Salary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily_Trigger": {
      "main": [
        [
          {
            "node": "Fetch_Today_Logs",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch_All_Employees",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log_Departure": {
      "main": [
        [
          {
            "node": "Msg_Departure_Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Model_Analyst": {
      "ai_languageModel": [
        [
          {
            "node": "Agent_Financial",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Calc_Absentees": {
      "main": [
        [
          {
            "node": "Msg_Absentee_Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Memory_Analyst": {
      "ai_memory": [
        [
          {
            "node": "Agent_Financial",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Agent_Financial": {
      "main": [
        [
          {
            "node": "Msg_Analysis_Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log_Transaction": {
      "main": [
        [
          {
            "node": "Msg_Attendance_Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lookup_Employee": {
      "main": [
        [
          {
            "node": "Check_Employee_Found",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Agent_Classifier": {
      "main": [
        [
          {
            "node": "Parse_AI_Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Agent_Onboarding": {
      "main": [
        [
          {
            "node": "Validate_New_Emp_JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch_Today_Logs": {
      "main": [
        [
          {
            "node": "Filter_Today_Attendance",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get_Arrival_Time": {
      "main": [
        [
          {
            "node": "Calc_Departure_Stats",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Model_Classifie
Pro

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

About this workflow

HR managers waste hours manually logging attendance, calculating work hours, and tracking salary advances in spreadsheets. Onboarding new staff often involves messy paperwork or scattered chat messages. Salary calculations are prone to errors when manually tallying absence,…

Source: https://n8n.io/workflows/13441/ — 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

&gt; AI-powered nutrition assistant for Telegram — log meals, set goals, and get personalized daily reports with Google Sheets integration.

Telegram, Google Gemini, Google Gemini Chat +7
AI & RAG

This automation is designed to help you generate AI-powered music tracks, cover art, and fully rendered music videos — all triggered from a simple Telegram chat and managed via Google Sheets.

OpenAI Chat, Memory Buffer Window, Output Parser Structured +11
AI & RAG

This workflow contains community nodes that are only compatible with the self-hosted version of n8n.

Output Parser Structured, Telegram, N8N Nodes Tesseractjs +14
AI & RAG

provides a foundational setup for creating powerful Telegram bots with n8n. It handles incoming messages, photos, files, and voice notes, making it an excellent starting point for developers looking t

Telegram Trigger, Telegram, Google Sheets +4
AI & RAG

Multi Agent System Benefits. Uses gmailTool, lmChatOpenAi, agent, googleCalendarTool. Event-driven trigger; 46 nodes.

Gmail Tool, OpenAI Chat, Agent +12