Team birthdays and work anniversaries on Slack

Every morning, celebrate today's birthdays and work anniversaries in your team channel.

Easy Saves ~1 hours/month HR & TeamBy Flowngn team

Works with n8n · Make · Zapier

How it works

Trigger: Schedule — every day at 9:00
  1. Read the Employees sheet (name, birthday, start date).
  2. Find birthdays and work anniversaries that fall today.
  3. Post one celebration message to Slack.

Diagram

Every day 9:00Schedule TriggerGRead employeesGoogle Sheets{ }Find today's celebr…CodeSPost to SlackSlack
Trigger App Code

Code

JavaScript used in the Code step — already included in the template below.

Find today's celebrations · Code node
// Employees sheet columns: name | birthday (YYYY-MM-DD) | start_date (YYYY-MM-DD) | department
// Finds today's birthdays and work anniversaries and builds one Slack message.
const now = new Date();
const md = (d) => `${d.getMonth() + 1}-${d.getDate()}`;
const today = md(now);

const lines = [];
for (const { json: e } of $input.all()) {
  if (e.birthday && md(new Date(e.birthday)) === today) {
    lines.push(`🎂 Happy birthday, ${e.name}!`);
  }
  if (e.start_date) {
    const start = new Date(e.start_date);
    const years = now.getFullYear() - start.getFullYear();
    if (years > 0 && md(start) === today) {
      lines.push(`🎉 ${e.name} has been with us ${years} year${years > 1 ? "s" : ""} today. Thank you!`);
    }
  }
}

if (!lines.length) return [];
return [{ json: { message: lines.join("\n") } }];

Build it

Pick your tool — same automation, step by step.

Copy and paste straight into an n8n canvas (Ctrl+V), or download and use Import from File. Then connect your own credentials and replace every YOUR_… placeholder.

Workflow JSON
Show code (139 lines)
{
  "name": "Team birthdays and work anniversaries on Slack (Flowngn)",
  "nodes": [
    {
      "parameters": {
        "content": "## Team birthdays and work anniversaries on Slack\nEvery morning, celebrate today's birthdays and work anniversaries in your team channel.\n\n**Setup**\n1. Open each node and connect your own credentials.\n2. Replace every YOUR_… placeholder.\n3. Test once, then activate.\n\nFree template from Flowngn",
        "height": 260,
        "width": 340
      },
      "id": "3da33d1f-ca34-490c-ab07-dfbd5de24b43",
      "name": "Setup notes",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -420,
        -60
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 9
            }
          ]
        }
      },
      "id": "3da33d1f-ca34-490c-ab07-dfbd5de24b43",
      "name": "Every day 9:00",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "operation": "read",
        "documentId": {
          "__rl": true,
          "value": "YOUR_SPREADSHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Employees",
          "mode": "name"
        },
        "options": {}
      },
      "id": "3da33d1f-ca34-490c-ab07-dfbd5de24b43",
      "name": "Read employees",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        300,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "// Employees sheet columns: name | birthday (YYYY-MM-DD) | start_date (YYYY-MM-DD) | department\n// Finds today's birthdays and work anniversaries and builds one Slack message.\nconst now = new Date();\nconst md = (d) => `${d.getMonth() + 1}-${d.getDate()}`;\nconst today = md(now);\n\nconst lines = [];\nfor (const { json: e } of $input.all()) {\n  if (e.birthday && md(new Date(e.birthday)) === today) {\n    lines.push(`🎂 Happy birthday, ${e.name}!`);\n  }\n  if (e.start_date) {\n    const start = new Date(e.start_date);\n    const years = now.getFullYear() - start.getFullYear();\n    if (years > 0 && md(start) === today) {\n      lines.push(`🎉 ${e.name} has been with us ${years} year${years > 1 ? \"s\" : \"\"} today. Thank you!`);\n    }\n  }\n}\n\nif (!lines.length) return [];\nreturn [{ json: { message: lines.join(\"\\n\") } }];"
      },
      "id": "3da33d1f-ca34-490c-ab07-dfbd5de24b43",
      "name": "Find today's celebrations",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        600,
        0
      ]
    },
    {
      "parameters": {
        "select": "channel",
        "channelId": {
          "__rl": true,
          "value": "#general",
          "mode": "name"
        },
        "text": "={{ $json.message }}",
        "otherOptions": {}
      },
      "id": "3da33d1f-ca34-490c-ab07-dfbd5de24b43",
      "name": "Post to Slack",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.2,
      "position": [
        900,
        0
      ]
    }
  ],
  "connections": {
    "Every day 9:00": {
      "main": [
        [
          {
            "node": "Read employees",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read employees": {
      "main": [
        [
          {
            "node": "Find today's celebrations",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find today's celebrations": {
      "main": [
        [
          {
            "node": "Post to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}

Open in the playground to edit →

Tips

  • Ask people before adding their birthday; some prefer not to share it.

Related flows