I recently built an automated email outreach system using n8n + OpenAI, and it only sends emails during the lead's local business hours.
Here’s what the flow looks like:
This is the code used to check for the
return items.map(item => {
// Use timezone from assistant's response (e.g. item.json.message.content)
const timezone = item.json.message?.content || "UTC";
try {
const now = new Date();
const formatter = new Intl.DateTimeFormat('en-US', {
timeZone: timezone,
hour: 'numeric',
hour12: false,
});
const parts = formatter.formatToParts(now);
const hour = parseInt(parts.find(p => p.type === 'hour')?.value || "0", 10);
return {
json: {
...item.json,
currentHour: hour,
isWithinBusinessHours: hour >= 8 && hour < 18,
timezoneChecked: timezone
}
};
} catch (err) {
return {
json: {
...item.json,
error: `Invalid timezone: ${timezone}`,
currentHour: null,
isWithinBusinessHours: false,
timezoneChecked: timezone
}
};
}
});
current time `
Why I Built This
Sending cold emails at 3 AM in the recipient's timezone? Bad idea.
This automation ensures:
- Higher open rates
- Professional timing
- Less chance of being marked as spam
Tools Used
- n8n – Automation logic and orchestration
- Google Sheets – Where I store leads
- OpenAI GPT – Detect timezone + generate emails
- Custom Delay Logic – Wait until local business hours
Workflow Steps
- Read leads from Google Sheets
- Check status (if they’ve already been emailed)
- Use OpenAI to infer the timezone (from country or city)
- Check the current hour in their timezone
- If too early/late, wait for 3 hours
- Once it’s a good time, generate a personalized email
- Send it, log it, and notify me of errors
Output
- Emails only go out between 9 AM–5 PM local time
- Each one is AI-personalized
- Everything is logged in Sheets
- I get notified once there is an error
Feedback?
I would love to hear:
- How do you scale or modularize this
- How to make it more robust for thousands of leads
- If there's a better approach for timezone detection
Let’s connect!
Thanks for reading
Top comments (0)