AutomationFlowsAI & RAG › Automate Hr Celebrations with Google Gemini, Sheets & Chat for Team Milestones

Automate Hr Celebrations with Google Gemini, Sheets & Chat for Team Milestones

ByDhruv Mali @dhruvmali on n8n.io

This workflow acts as your automated HR assistant, scanning for employee milestones and posting AI-generated celebration messages to Google Chat.

Cron / scheduled trigger★★★★☆ complexityAI-powered24 nodesGoogle Gemini ChatChain LlmHTTP RequestGoogle Sheets
AI & RAG Trigger: Cron / scheduled Nodes: 24 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Chainllm → 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
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "43546caa-723d-4754-bf75-2947ca6e0dac",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1136,
        160
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 9
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "12f3c9e6-bec6-4ede-aa27-fed89c3a8663",
      "name": "If Birthday not found",
      "type": "n8n-nodes-base.if",
      "position": [
        -240,
        160
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "330e982f-fb41-4a4c-aa62-8d930ff8bdcf",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "NO_BIRTHDAY_TODAY"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "99abba63-2a58-45a0-b108-9f28944d1d26",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -16,
        160
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "16599b97-138c-427b-b79c-c773f8ee8012",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        288,
        144
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "0a0a554a-caf4-4603-bed3-304ede7c2946",
      "name": "Schedule Trigger1",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1152,
        688
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 9
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "8fc2227a-b959-4693-a064-e631d767025f",
      "name": "Loop Over Items1",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        176,
        688
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "ce2d374b-9de7-47aa-88cf-87fe118899bd",
      "name": "Google Gemini Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        480,
        784
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "5979fe9f-01d8-40c7-ac3a-5cc946c56ae6",
      "name": "Anniversary message",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        400,
        560
      ],
      "parameters": {
        "text": "=Act as a friendly and professional HR communications assistant. Your task is to craft a warm and professional work anniversary message for an employee named {{ $json.matches[0].name }}, who is celebrating their {{ $json.matches[0].yearsOfService }} year(s) with the company.\n\nThis message will be posted in a company-wide group chat, so it must be respectful, inclusive, and celebratory.\n\nFollow these strict rules:\n\nAcknowledge the Milestone: Clearly mention the number of years they are celebrating.\n\nKeep it concise: The entire message should be 2-3 sentences long.\n\nMaintain a positive and appreciative tone.\n\nBe genuine: Focus on their journey, growth, and contributions over the years.\n\nEnsure variety: Do not use the same phrases every time. Generate a fresh, unique message for each request.\n\nABSOLUTELY NO jokes, overly casual slang, or anything that could be misinterpreted.\n\nEnd the main wish by encouraging the team to join in the congratulations.\n\nALWAYS conclude the entire message with the signature on a new line: - From Saeculum Team\n\nHere are some examples of the desired style and format:\n\nExample 1:\n\"A huge congratulations to {{ $json.matches[0].name }}  on celebrating {{ $json.matches[0].yearsOfService }} years with us! Your dedication and expertise have been invaluable. Please join us in wishing them a happy work anniversary!\n\nFrom  {{ $('SET - ANNIVERSARY').first().json['Agency Name'] }} Team\"\n \nExample 2:\n\"Happy Work Anniversary,{{ $json.matches[0].name }}! It's been {{ $json.matches[0].yearsOfService }} incredible years, and we're so grateful for the commitment you've shown. Let's all congratulate them on this amazing milestone!\n\nFrom {{ $('SET - ANNIVERSARY').first().json['Agency Name'] }} Team\"\n\nExample 3:\n\"Let's all give a big round of applause for {{ $json.matches[0].name }}, who marks {{ $json.matches[0].yearsOfService }} years at Saeculum today! Thank you for being such a vital part of our journey.\n\nFrom {{ $('SET - ANNIVERSARY').first().json['Agency Name'] }} Team\"\n\nNow, generate a new work anniversary wish for {{ $json.matches[0].name }} celebrating {{ $json.matches[0].yearsOfService }} year(s).",
        "batching": {},
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "eff3dcbc-4eb5-4777-bb68-2fa1b9172ad8",
      "name": "Birthday Message",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        208,
        -80
      ],
      "parameters": {
        "text": "=Act as a friendly and professional HR communications assistant. Your task is to craft a warm and professional birthday wish for an employee named {{ $json['EMPLOYEE NAME '] }}.\n\nThis message will be posted in a company-wide group chat, so it must be respectful, inclusive, and celebratory.\n\nFollow these strict rules:\n\nKeep it concise: The entire message should be 2-3 sentences long.\n\nMaintain a positive and uplifting tone.\n\nBe genuine: Focus on appreciation for their contribution or positive presence in the team.\n\nEnsure variety: Do not use the same phrases every time. Generate a fresh, unique message for each request.\n\nABSOLUTELY NO clich\u00e9s (like \"another trip around the sun\"), jokes, overly casual slang, or anything that could be misinterpreted.\n\nEnd the main wish by encouraging the team to join in.\n\nALWAYS conclude the entire message with the signature on a new line: - From Saeculum Team\n\nHere are some examples of the desired style and format:\n\nExample 1:\n\"Happy Birthday, {{ $json['EMPLOYEE NAME '] }}! Your dedication and positive energy are a huge asset to our team. Wishing you a fantastic day and a wonderful year ahead. Let's all wish them the best!\n\nFrom {{ $('SET-BIRTHDAY').item.json['Agency Name'] }} Team\"\n\nExample 2:\n\"A very happy birthday to {{ $json['EMPLOYEE NAME '] }}! Thank you for all the great work you do. We hope you have an amazing day of celebration. Please join us in sending your best wishes!\n\nFrom {{ $('SET-BIRTHDAY').item.json['Agency Name'] }} Team\"\n\nExample 3:\n\"Join us in wishing a huge happy birthday to {{ $json['EMPLOYEE NAME '] }}! Your contributions make a big difference, and we're so glad to have you on the team. Have a great one!\n\nFrom {{ $('SET-BIRTHDAY').item.json['Agency Name'] }} Team\"\n\nNow, generate a new birthday wish for {{ $json[\"EMPLOYEE NAME \"] }}.",
        "batching": {},
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "c1adfaa9-3583-4acb-b11c-2b82f98d22d6",
      "name": "SET - ANNIVERSARY",
      "type": "n8n-nodes-base.set",
      "position": [
        -928,
        688
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "e0dd1dce-2479-45f6-b6bb-640329809f68",
              "name": "Agency Name",
              "type": "string",
              "value": "your agency name"
            },
            {
              "id": "b49eec37-d83a-42fe-b0c2-677a3976d71f",
              "name": "google chat api key",
              "type": "string",
              "value": "<your_api_key>"
            },
            {
              "id": "f8f293b7-f6f2-4c29-abf3-4bed9ee19745",
              "name": "google chat space id",
              "type": "string",
              "value": "<gchat_space_id>"
            },
            {
              "id": "37b1fc32-dd2b-4ead-8352-f5d320c0b6fc",
              "name": "google chat token",
              "type": "string",
              "value": "<gchat_token>"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "450d7802-8dfa-497d-a0b3-3398581822da",
      "name": "SET-BIRTHDAY",
      "type": "n8n-nodes-base.set",
      "position": [
        -912,
        160
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "e0dd1dce-2479-45f6-b6bb-640329809f68",
              "name": "Agency Name",
              "type": "string",
              "value": "your agency name"
            },
            {
              "id": "b49eec37-d83a-42fe-b0c2-677a3976d71f",
              "name": "google chat api key",
              "type": "string",
              "value": "<your_api_key>"
            },
            {
              "id": "f8f293b7-f6f2-4c29-abf3-4bed9ee19745",
              "name": "google chat space id",
              "type": "string",
              "value": "<gchat_space_id>"
            },
            {
              "id": "37b1fc32-dd2b-4ead-8352-f5d320c0b6fc",
              "name": "google chat token",
              "type": "string",
              "value": "<gchat_token>"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "020ffe25-3572-492a-a491-9b6e713f3c01",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1856,
        224
      ],
      "parameters": {
        "width": 512,
        "height": 544,
        "content": "## \ud83c\udf82 Automate Employee Celebrations\nNever miss a team milestone. This workflow checks for birthdays and anniversaries daily, drafts unique AI messages, and posts them to Google Chat.\n\n## How it works\n1. **Configuration:** You define your Agency Name and Chat credentials once in the \"SET\" nodes.\n2. **Daily Scan:** Checks your Google Sheet every morning at 9:00 AM.\n3. **AI Writing:** Google Gemini drafts a personalized, non-repetitive message.\n4. **Delivery:** Posts to Google Chat and logs the event.\n\n## Setup Steps\n1. **Credentials:** Connect your Google Sheets and Google Gemini accounts in the nodes.\n2. **Configuration:** Open the `SET-BIRTHDAY` and `SET - ANNIVERSARY` nodes. Replace the placeholder values with your **Agency Name**, **Google Chat Space ID**, **Key**, and **Token**.\n3. **Sheet:** Ensure your Google Sheet has columns for `Employee DOB` and `Date Joined`."
      },
      "typeVersion": 1
    },
    {
      "id": "2167a8f0-1792-40d4-9f90-e8d01c793757",
      "name": "Today",
      "type": "n8n-nodes-base.set",
      "position": [
        -496,
        688
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "072e7990-91e4-4fe3-a636-784d75bbafe9",
              "name": "todayIso",
              "type": "string",
              "value": "={{$today}}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "bcaf98b5-fbf2-4a41-a319-771c56d830a0",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1200,
        -112
      ],
      "parameters": {
        "color": 4,
        "width": 2176,
        "height": 528,
        "content": "## 1. Birthday Automation\n### Checks for birthdays today. It uses the credentials configured in the `SET-BIRTHDAY` node to send an AI-generated wish to your chat space."
      },
      "typeVersion": 1
    },
    {
      "id": "44943a7f-8492-4447-9bc4-12c826af793f",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1200,
        496
      ],
      "parameters": {
        "color": 4,
        "width": 2368,
        "height": 496,
        "content": "## 2. Work Anniversary Automation\nCalculates years of service based on the joining date. Configured via the `SET - ANNIVERSARY` node, it sends a milestone-specific message to the team."
      },
      "typeVersion": 1
    },
    {
      "id": "001bfe72-aff8-4bf8-b535-69643118399b",
      "name": "GCHAT_ANNI",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "maxTries": 2,
      "position": [
        752,
        560
      ],
      "parameters": {
        "url": "=https://chat.googleapis.com/v1/spaces/{{ $('SET - ANNIVERSARY').item.json['google chat space id'] }}/messages?key={{ $('SET - ANNIVERSARY').item.json['google chat api key'] }}&token={{ $('SET - ANNIVERSARY').item.json['google chat token'] }}",
        "method": "POST",
        "options": {},
        "jsonBody": "={\"text\": {{ JSON.stringify($json.text) }}}",
        "sendBody": true,
        "specifyBody": "json"
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 5000
    },
    {
      "id": "222f270e-c977-445a-9e86-007243de1ad8",
      "name": "GCHAT_BDAY",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "maxTries": 2,
      "position": [
        560,
        32
      ],
      "parameters": {
        "url": "=https://chat.googleapis.com/v1/spaces/{{ $('SET-BIRTHDAY').item.json['google chat space id'] }}/messages?key={{ $('SET-BIRTHDAY').item.json['google chat api key'] }}&token={{ $('SET-BIRTHDAY').item.json['google chat token'] }}",
        "method": "POST",
        "options": {},
        "jsonBody": "={\"text\": {{ JSON.stringify($json.text) }}}",
        "sendBody": true,
        "specifyBody": "json"
      },
      "retryOnFail": true,
      "typeVersion": 4.2,
      "waitBetweenTries": 5000
    },
    {
      "id": "1d4c331d-d1ab-4474-a025-46192e314b1a",
      "name": "Parse birthday",
      "type": "n8n-nodes-base.code",
      "position": [
        -464,
        160
      ],
      "parameters": {
        "jsCode": "// This code checks a list of employees from your Google Sheet\n// and finds everyone who has a birthday today.\n\n// This array will hold the employees we find.\nconst birthdayEmployees = [];\n\n// 1. Get today's date. This is dynamic and changes every day.\nconst today = new Date();\nconst currentMonth = today.getMonth(); // 0 for January, 1 for February, etc.\nconst currentDay = today.getDate();\n\n// 2. Loop through every employee record that comes from the Google Sheets node.\n// 'items' is the standard n8n variable for the incoming data.\nfor (const item of items) {\n  // IMPORTANT: Make sure the key here EXACTLY matches your column header in Google Sheets.\n  const dobString = item.json[\"Employee DOB\"];\n\n  // We only run the check if a date of birth exists for the employee.\n  if (dobString) {\n    // 3. Convert the employee's birthday text into a real date object.\n    // The JavaScript `new Date()` is smart enough to understand formats like\n    // \"13-Oct-1990\" and \"09-June-2004\".\n    const employeeDob = new Date(dobString);\n\n    // Just to be safe, we check if the date is a valid one.\n    if (!isNaN(employeeDob.getTime())) {\n      const employeeBirthMonth = employeeDob.getMonth();\n      const employeeBirthDay = employeeDob.getDate();\n\n      // 4. THE BIG CHECK: Does the employee's birth month and day match today's?\n      if (currentMonth === employeeBirthMonth && currentDay === employeeBirthDay) {\n        // It's a match! Add this employee to our birthday list.\n        birthdayEmployees.push(item);\n      }\n    }\n  }\n}\n\n// 5. Return the result based on whether we found anyone.\nif (birthdayEmployees.length > 0) {\n  // If anyone has a birthday, return their data to the next node.\n  return birthdayEmployees;\n} else {\n  // If no one has a birthday, return a single item with a special status.\n  // This makes it easy to check in the next IF node.\n  return [{\n    json: {\n      status: \"NO_BIRTHDAY_TODAY\"\n    }\n  }];\n}\n\n"
      },
      "typeVersion": 2,
      "alwaysOutputData": false
    },
    {
      "id": "c8f0c6ff-8bfe-474a-aed0-ac8d12dd229f",
      "name": "Get dates-ANNI",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -704,
        688
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 844036640,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1pueg5YHB8vOzqwqmk72Nrph1IVcoyBvitPYUkJ7tHMg/edit#gid=844036640",
          "cachedResultName": "Work Anni"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1pueg5YHB8vOzqwqmk72Nrph1IVcoyBvitPYUkJ7tHMg",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1pueg5YHB8vOzqwqmk72Nrph1IVcoyBvitPYUkJ7tHMg/edit?usp=drivesdk",
          "cachedResultName": "Copy of N8N Wishes Excel"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "60ae461f-bd8d-4813-99ff-a1de8b771765",
      "name": "Get dates-BDAY",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -688,
        160
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1pueg5YHB8vOzqwqmk72Nrph1IVcoyBvitPYUkJ7tHMg/edit#gid=0",
          "cachedResultName": "Birthday List"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1pueg5YHB8vOzqwqmk72Nrph1IVcoyBvitPYUkJ7tHMg",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1pueg5YHB8vOzqwqmk72Nrph1IVcoyBvitPYUkJ7tHMg/edit?usp=drivesdk",
          "cachedResultName": "Copy of N8N Wishes Excel"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "589ebf22-a664-4a5b-b1c1-8f8625b3cf87",
      "name": "parse ANNIVESARY",
      "type": "n8n-nodes-base.code",
      "position": [
        -272,
        688
      ],
      "parameters": {
        "jsCode": "// n8n Function node \u2014 single-item output with status + matches\n// REQUIRE: Set node before this with todayIso = {{$today}}\n\nconst todayIso = items[0]?.json?.todayIso;\nif (!todayIso) return [{ json: { status: \"ERROR_MISSING_TODAY\", matches: [] } }];\n\nconst [TY, TM, TD] = String(todayIso).slice(0,10).split('-').map(Number);\nconst currentYear = TY, currentMonthIndex = TM - 1, currentDay = TD;\n\nconst monthMap = { jan:0,feb:1,mar:2,apr:3,may:4,jun:5,jul:6,aug:7,sep:8,sept:8,oct:9,nov:10,dec:11 };\n\nfunction normYear(y) {\n  y = Number(y);\n  if (isNaN(y)) return null;\n  if (y < 100) {\n    const cutoff = currentYear % 100;\n    return y <= cutoff ? 2000 + y : 1900 + y;\n  }\n  return y;\n}\n\nfunction parseJoin(s) {\n  if (!s) return null;\n  s = String(s).trim();\n  let m = s.match(/^(\\d{1,2})[\\/\\-](\\d{1,2})[\\/\\-](\\d{2,4})$/);\n  if (m) return { d:+m[1], m:+m[2]-1, y: normYear(m[3]) };\n  m = s.match(/^(\\d{1,2})[^\\w\\d]+([A-Za-z]+)[^\\w\\d]+(\\d{2,4})$/);\n  if (m) {\n    const token = m[2].toLowerCase().replace(/[^a-z]/g,'');\n    const mi = monthMap[token.slice(0,3)] ?? monthMap[token];\n    return mi !== undefined ? { d:+m[1], m:mi, y: normYear(m[3]) } : null;\n  }\n  return null;\n}\n\nconst matches = [];\n\nfor (const it of items) {\n  const raw =\n    it.json?.[\"Date Joined \\n(dd-MMM-yyyy)\"] ??\n    it[\"Date Joined \\n(dd-MMM-yyyy)\"] ??\n    it.json?.[\"Date Joined\"] ??\n    it[\"Date Joined\"];\n\n  const p = parseJoin(raw);\n  if (!p) continue;\n\n  // skip future join dates\n  if (p.y > currentYear || (p.y === currentYear && (p.m > currentMonthIndex || (p.m === currentMonthIndex && p.d > currentDay)))) continue;\n\n  if (p.m === currentMonthIndex && p.d === currentDay) {\n    const yearsOfService = currentYear - p.y;\n    if (yearsOfService >= 1) {\n      // build a compact match object (keeps original row fields + years)\n      const match = {\n        row_number: it.row_number ?? it.json?.row_number ?? null,\n        name: it[\"EMPLOYEE NAME \"] ?? it.json?.[\"EMPLOYEE NAME \"] ?? null,\n        dateJoinedRaw: raw,\n        parsedJoinDate: `${p.y}-${String(p.m+1).padStart(2,'0')}-${String(p.d).padStart(2,'0')}`,\n        yearsOfService\n      };\n      matches.push(match);\n    }\n  }\n}\n\n// single item output: status + matches array\nif (matches.length > 0) {\n  return [{ json: { status: \"ANNIVERSARY_FOUND\", matches } }];\n}\nreturn [{ json: { status: \"NO_ANNIVERSARY_TODAY\", matches: [] } }];\n"
      },
      "typeVersion": 2,
      "alwaysOutputData": false
    },
    {
      "id": "59289cc9-7150-4232-aa34-29fa008b93d7",
      "name": "If Anniversary not found",
      "type": "n8n-nodes-base.if",
      "position": [
        -48,
        688
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "330e982f-fb41-4a4c-aa62-8d930ff8bdcf",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "NO_ANNIVERSARY_TODAY"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "b66ec152-0cae-4151-b1b7-56a4c13ffe8f",
      "name": "Log msg -Bday",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        784,
        160
      ],
      "parameters": {
        "columns": {
          "value": {
            "TimeStamp": "={{ $now }}",
            "Event Type": "Birthday ",
            "Employee Name": "={{ $('Loop Over Items').first().json[\"EMPLOYEE NAME \"] }}"
          },
          "schema": [
            {
              "id": "TimeStamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "TimeStamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Event Type",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Event Type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Employee Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Employee Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1953520783,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1HLlT5lx_YOUR_AWS_SECRET_KEY_HERE#gid=1953520783",
          "cachedResultName": "Logs"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1HLlT5lx_rwuARc6TZ3L0AS2PRxujwTUyElHkwctFpHw",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1HLlT5lx_YOUR_AWS_SECRET_KEY_HERE?usp=drivesdk",
          "cachedResultName": "N8N Wishes Excel"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "2aed8156-500c-476f-9152-4c44f310f45c",
      "name": "Log msg - ANNI",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        976,
        688
      ],
      "parameters": {
        "columns": {
          "value": {
            "TimeStamp": "={{ $now }}",
            "Event Type": "Anniversary",
            "Employee Name": "={{ $('Loop Over Items1').first().json.matches[0].name }}"
          },
          "schema": [
            {
              "id": "TimeStamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "TimeStamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Event Type",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Event Type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Employee Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Employee Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1953520783,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1HLlT5lx_YOUR_AWS_SECRET_KEY_HERE#gid=1953520783",
          "cachedResultName": "Logs"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1HLlT5lx_rwuARc6TZ3L0AS2PRxujwTUyElHkwctFpHw",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1HLlT5lx_YOUR_AWS_SECRET_KEY_HERE?usp=drivesdk",
          "cachedResultName": "N8N Wishes Excel"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    }
  ],
  "connections": {
    "Today": {
      "main": [
        [
          {
            "node": "parse ANNIVESARY",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GCHAT_ANNI": {
      "main": [
        [
          {
            "node": "Log msg - ANNI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GCHAT_BDAY": {
      "main": [
        [
          {
            "node": "Log msg -Bday",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SET-BIRTHDAY": {
      "main": [
        [
          {
            "node": "Get dates-BDAY",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log msg -Bday": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get dates-ANNI": {
      "main": [
        [
          {
            "node": "Today",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get dates-BDAY": {
      "main": [
        [
          {
            "node": "Parse birthday",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log msg - ANNI": {
      "main": [
        [
          {
            "node": "Loop Over Items1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse birthday": {
      "main": [
        [
          {
            "node": "If Birthday not found",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Birthday Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Birthday Message": {
      "main": [
        [
          {
            "node": "GCHAT_BDAY",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items1": {
      "main": [
        [],
        [
          {
            "node": "Anniversary message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "SET-BIRTHDAY",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "parse ANNIVESARY": {
      "main": [
        [
          {
            "node": "If Anniversary not found",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SET - ANNIVERSARY": {
      "main": [
        [
          {
            "node": "Get dates-ANNI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger1": {
      "main": [
        [
          {
            "node": "SET - ANNIVERSARY",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Anniversary message": {
      "main": [
        [
          {
            "node": "GCHAT_ANNI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Birthday not found": {
      "main": [
        [],
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Birthday Message",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "If Anniversary not found": {
      "main": [
        [],
        [
          {
            "node": "Loop Over Items1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Anniversary message",
            "type": "ai_languageModel",
            "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 acts as your automated HR assistant, scanning for employee milestones and posting AI-generated celebration messages to Google Chat.

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

This workflow is the AI analysis and alerting engine for a complete social media monitoring system. It's designed to work with data scraped from X (formerly Twitter) using a tool like the Apify Tweet

Google Sheets, Google Gemini Chat, Google Sheets Tool +4
AI & RAG

Categories Content Creation AI Automation Publishing Social Media

Google Docs, HTTP Request, Slack +7
AI & RAG

Effortlessly generate, review, and publish SEO-optimized blog posts to WordPress using AI and automation.

WordPress, Google Gemini Chat, Output Parser Structured +6
AI & RAG

This n8n workflow automatically monitors YouTube channels, transcribes new videos, and generates AI-powered summaries with relevance scoring. It pulls channel URLs from a Google Sheet, fetches recent

Output Parser Structured, Google Gemini Chat, Chain Llm +2
AI & RAG

Transform your festival marketing with this comprehensive automation workflow that creates and posts culturally authentic social media content across multiple platforms daily.

Google Sheets, Output Parser Structured, Chain Llm +5