Automate Employee Date Tracking & Reminders for HR with JavaScript

Go to Workflow
6 views
Built by David Olusola David Olusola
Created on June 06, 2026

Description

HR Date Management Automation - Complete Setup Guide

🎯 How It Works

This n8n workflow transforms your HR department from reactive to proactive by automatically monitoring 5 critical employee timelines and generating smart alerts before deadlines hit.

Core Components

Data Input → Employee information (hire dates, contracts, certifications)
Date Analysis Engine → Calculates days until critical events
Smart Categorization → Sorts employees by urgency level
Reminder Scheduler → Creates proactive notifications
Multi-Format Export → Sends alerts to your preferred systems

Business Value

Prevents compliance violations** ($5K-50K+ in fines)
Reduces HR workload** (15-20 hours/month saved)
Improves employee experience** (no missed reviews/renewals)
Provides management visibility** (dashboard reporting)

🚀 Quick Start Test

1. Import the Workflow

Download the Javascript_Hr.json file
Open n8n and click “Import from file”
Select the downloaded JSON file
Click “Import”

2. Test with Sample Data

Click the “Execute Workflow” button
Review the sample output in each node
Check the final export data format

What you’ll see:

5 sample employees with different scenarios
Calculated days until contract/certification expiry
Priority levels (high/medium/low)
Scheduled reminders with recipient emails
Export data in multiple formats

🔧 Real-World Integration Setup

Option 1: Google Sheets Integration (Most Popular)

Step 1: Prepare Your Employee Data

Create a Google Sheet with these columns:

| Employee ID | Name | Email | Department | Hire Date | Contract End | Certification Expiry | Last Review | Probation End | Vacation Days | Status |

Sample data format:

| 1 | John Smith | [email protected] | IT | 2024-01-15 | 2025-12-31 | 2025-03-20 | 2024-06-15 | 2024-07-15 | 20 | active |

Step 2: Replace Sample Data Generator

Delete the “Sample Data Generator” node
Add “Google Sheets” node
Connect to your Google account
Configure these settings:
Operation**: Read
Document**: Your employee spreadsheet
Sheet**: Employee data sheet
Range**: A1:K100 (adjust for your data size)
Options**: ✅ RAW data, ✅ Header row

Step 3: Map Your Data

Add a “Set” node after Google Sheets to standardize field names:

// Map your sheet columns to workflow format
{
"id": "{{ $json['Employee ID'] }}",
"name": "{{ $json['Name'] }}",
"email": "{{ $json['Email'] }}",
"department": "{{ $json['Department'] }}",
"hiredOn": "{{ $json['Hire Date'] }}",
"contractEndDate": "{{ $json['Contract End'] }}",
"certificationExpiry": "{{ $json['Certification Expiry'] }}",
"lastReviewDate": "{{ $json['Last Review'] }}",
"probationEndDate": "{{ $json['Probation End'] }}",
"vacationDays": "{{ $json['Vacation Days'] }}",
"status": "{{ $json['Status'] }}"
}

Option 2: HRIS Integration (BambooHR Example)

Step 1: BambooHR API Setup

Get your BambooHR API key from Settings > API Keys
Note your company subdomain (e.g., yourcompany.bamboohr.com)

Step 2: Replace Sample Data Generator

Delete the “Sample Data Generator” node
Add “HTTP Request” node
Configure these settings:
Method**: GET
URL**: https://api.bamboohr.com/api/gateway.php/[SUBDOMAIN]/v1/employees/directory
Authentication**: Basic Auth
Username**: Your API key
Password**: x (leave as ‘x’)
Headers**: Accept: application/json

Step 3: Transform BambooHR Data

Add a “Code” node to transform the API response:

// Transform BambooHR response to workflow format
const employees = [];

for (const employee of $input.all()) {
const emp = employee.json;

employees.push({
id: emp.id,
name: ${emp.firstName} ${emp.lastName},
email: emp.workEmail,
department: emp.department,
hiredOn: emp.hireDate,
contractEndDate: emp.terminationDate || "2025-12-31", // Default if not set
certificationExpiry: emp.customCertDate || "2025-12-31",
lastReviewDate: emp.customReviewDate || null,
probationEndDate: emp.customProbationDate || null,
vacationDays: emp.paidTimeOff || 20,
status: emp.employeeStatus || "active"
});
}

return employees.map(emp => ({ json: emp }));

Option 3: CSV File Upload

Step 1: Prepare CSV File

Create a CSV with the same structure as the Google Sheets format.

Step 2: Use CSV Parser

Replace “Sample Data Generator” with “Read Binary File” node
Add “CSV Parser” node
Configure settings:
Include Headers**: Yes
Delimiter**: Comma
Skip Empty Lines**: Yes

📧 Output Integration Setup

Email Notifications

Step 1: Add Email Node

Add “Email” node after “Reminder Scheduler”
Connect to your email provider (Gmail/Outlook)

Step 2: Configure Email Templates

// Dynamic email content based on reminder type
const reminder = $json;

const emailTemplates = {
contract_renewal: {
subject: 🚨 Contract Renewal Required - ${reminder.employeeName},
body: `
Hi HR Team,

${reminder.employeeName}'s contract expires on ${reminder.dueDate}.

Days remaining: ${Math.ceil((new Date(reminder.dueDate) - new Date()) / (10006060*24))}

Please initiate renewal process immediately.

Best regards,
HR Automation System
`
},
certification_renewal: {
subject: 📜 Certification Renewal Reminder - ${reminder.employeeName},
body: `
Hi ${reminder.employeeName},

Your certification expires on ${reminder.dueDate}.

Please renew your certification to maintain compliance.

Contact HR if you need assistance.

Best regards,
HR Team
`
}
};

const template = emailTemplates[reminder.type];
return {
to: reminder.recipientEmail,
subject: template.subject,
body: template.body
};

Slack Integration

Step 1: Add Slack Node

Add “Slack” node after “Advanced Date Filters”
Connect to your Slack workspace

Step 2: Configure Channel Alerts

// Send summary to #hr-alerts channel
const summary = $json.summary;

const message = `
🏢 Daily HR Report

👥 Total Employees: ${summary.totalEmployees}
🆕 New Hires: ${summary.newHires}
⚠️ High Priority Actions: ${summary.highPriority}
📋 Contracts Expiring: ${summary.contractsExpiring}
🎓 Certifications Expiring: ${summary.certificationsExpiring}

Generated: ${new Date().toLocaleDateString()}
`;

return {
channel: '#hr-alerts',
text: message
};

Google Calendar Integration

Step 1: Add Calendar Node

Add “Google Calendar” node after “Reminder Scheduler”
Connect to your Google account

Step 2: Create Calendar Events

// Create calendar events for upcoming deadlines
const reminder = $json;

const eventTitles = {
contract_renewal: Contract Renewal - ${reminder.employeeName},
certification_renewal: Certification Renewal - ${reminder.employeeName},
performance_review: Performance Review - ${reminder.employeeName},
probation_review: Probation Review - ${reminder.employeeName}
};

return {
calendarId: '[email protected]',
summary: eventTitles[reminder.type],
description: reminder.message,
start: {
dateTime: reminder.dueDate,
timeZone: 'America/New_York'
},
end: {
dateTime: reminder.dueDate,
timeZone: 'America/New_York'
},
attendees: [
{ email: '[email protected]' },
{ email: reminder.recipientEmail }
]
};

🎯 Scheduling & Automation

Daily Monitoring Setup

Step 1: Add Cron Trigger

Replace “Manual Trigger” with “Cron” node
Set schedule: 0 9 * * 1-5 (9 AM, Monday-Friday)
Configure timezone to your business hours

Step 2: Error Handling

Add “Error Trigger” node
Connect to email notification for failures
Set up retry logic for failed integrations

Weekly Reports

Step 1: Create Weekly Summary

Add separate “Cron” trigger for weekly reports
Set schedule: 0 9 * * 1 (9 AM every Monday)
Modify the filtering logic to show weekly trends

🔍 Customization Options

Adjust Alert Timings

In the “Date Analysis & Categorization” node:

// Modify these values to change alert timing
const isContractExpiringSoon = daysUntilContractEnd <= 90; // Change from 90 days
const isCertificationExpiringSoon = daysUntilCertificationExpiry <= 60; // Change from 60 days
const needsReview = daysSinceLastReview >= 365; // Change from 365 days

Add Custom Employee Categories

// Add new categories in the analysis node
const isContractor = employee.employeeType === 'contractor';
const isRemoteWorker = employee.location === 'remote';
const isHighRisk = employee.performanceRating === 'needs_improvement';

Custom Date Formats

Modify the “Date Formatting & Export” node to add your preferred formats:

// Add custom date format
const formatters = {
custom: (date) => {
const options = {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long'
};
return date.toLocaleDateString('en-US', options);
}
};

🎚️ Testing & Validation

Step 1: Data Validation

Test with 2-3 sample employees first
Verify all dates are parsing correctly
Check that calculations match manual calculations

Step 2: Alert Testing

Create test scenarios with dates 30/60/90 days out
Verify emails are sent to correct recipients
Test Slack notifications in a test channel

Step 3: Performance Testing

Test with your full employee dataset
Monitor execution time (should be under 30 seconds)
Check for memory usage with large datasets

🆘 Troubleshooting Guide

Common Issues

Date Parsing Errors

// Add date validation in the analysis node
const parseDate = (dateStr) => {
const date = new Date(dateStr);
if (isNaN(date.getTime())) {
console.error(Invalid date: ${dateStr});
return null;
}
return date;
};

Missing Data Fields

// Add data validation
const validateEmployee = (employee) => {
const required = ['name', 'email', 'hiredOn'];
const missing = required.filter(field => !employee[field]);

if (missing.length > 0) {
console.error(Missing required fields for ${employee.name}: ${missing.join(', ')});
return false;
}
return true;
};

API Rate Limits

Add “Wait” nodes between API calls
Implement retry logic with exponential backoff
Cache API responses when possible

🚀 Advanced Features

Multi-Company Support

// Add company filtering in the analysis node
const processEmployeesByCompany = (employees, companyId) => {
return employees.filter(emp => emp.companyId === companyId);
};

Custom Notification Rules

// Advanced notification logic
const shouldNotify = (employee, eventType) => {
const rules = {
contract_renewal: employee.department !== 'intern',
certification_renewal: employee.role === 'certified_professional',
performance_review: employee.status === 'active'
};

return rules[eventType] || false;
};

Integration with Time Tracking

// Connect to time tracking APIs
const calculateWorkingDays = (startDate, endDate) => {
// Implementation for working days calculation
// Excluding weekends and holidays
};

This workflow transforms your HR department from reactive to proactive, preventing costly compliance issues while improving employee experience. The modular design allows you to start simple and add complexity as needed.

Nodes Used (5)

Code
n8n-nodes-base.code
Gmail
n8n-nodes-base.gmail
Google Calendar
n8n-nodes-base.googleCalendar
Google Sheets
n8n-nodes-base.googleSheets
Slack
n8n-nodes-base.slack