Overview
This guide shows you how to build an n8n workflow that notifies your team in Slack whenever a previously-identified visitor returns to your website.
In this example, we use Slack to send alerts.
Feel free to use any tools your tech stack supports — HubSpot, Salesforce, Teams, email, etc. The logic stays the same.
This workflow is ideal for:
Account-based outreach
High-intent visitor alerts
Notifying sales when warm visitors come back
Re-engagement monitoring
Lead scoring based on multi-day activity
It builds on your primary RB2B visitor-tracking workflow and branches directly from your existing Build Returning Visitor Row node.
What This Workflow Does
Each time RB2B identifies a visitor:
This returning-visitor branch then checks whether the visitor has come back on a different day than before.
If so, the workflow:
builds a Slack message
sends an alert to your chosen Slack channel
If not, the workflow ends quietly with no alert.
This gives your team real-time visibility into meaningful repeat engagement.
Step-By-Step Workflow
Below is every node involved in this returning-visitor alert branch, in order.
1. IF Node: Check if Returning Over Multiple Days
Branching off the Build Returning Visitor Row node, this node checks if the visitor has returned on a different calendar day than their previous visit.
Condition 1: {{ $json.unique_days_count }} is greater than 1
Condition 2: {{ $json.company_name }} is not empty
This means:
If the visitor has been seen on more than one unique day, the workflow continues to the Slack alert.
If the visitor’s visits happened only on a single day, the workflow ends with no alert.
The second condition is a quick check to make sure that we've captured a company name for the visitor as well.
This prevents noise from same-day page views and focuses on meaningful return activity.
2. Code Node: Build Returning Visitor Slack Block (Code)
This node builds a message like:
‼️ RETURN VISITOR DETECTED ‼️
John Doe from RB2B
Head of Example Code
Email: [email protected]
LinkedIn: http://www.linkedin.com/company/rb2b
Total page views: 7
Unique days visited: 4
Visit history by day:
• 2025-11-19
- https://www.rb2b.com/apis
• 2025-11-18
- https://www.rb2b.com/apis
- https://www.rb2b.com/pricing
- https://www.rb2b.com/apis
The node outputs a single value:
slack_text
Code:
const person = $json;
// Basic identity info
const firstName = person.first_name || "Anonymous";
const lastName = person.last_name || "Visitor";
const fullName = `${firstName} ${lastName}`.trim();
const company = person.company_name || "Unknown company";
const email = person.business_email || "no email";
const website = person.website || "";
const title = person.title || "";
const linkedin = person.identity_key || "";
const pageViews = person.page_views || 0;
// Parse all_pages array
let allPages = [];
try {
allPages = JSON.parse(person.all_pages || "[]");
} catch (e) {
allPages = [];
}
// Group pages by date (YYYY-MM-DD)
const daysMap = {};
for (const p of allPages) {
if (!p.seen_at) continue;
const day = p.seen_at.slice(0, 10); // "YYYY-MM-DD"
const url = p.url || "(unknown URL)";
if (!daysMap[day]) daysMap[day] = [];
daysMap[day].push(url);
}
// Sort days (latest first)
const days = Object.keys(daysMap).sort().reverse();
const uniqueDaysCount = days.length;
// Build Slack message lines
const lines = [];
lines.push(`‼️ *RETURN VISITOR DETECTED* ‼️`);
lines.push(`*${fullName}* from *${company}*`);
if (title) lines.push(`${title}`);
lines.push(`*Email:* ${email}`);
lines.push(`*LinkedIn:* ${linkedin}`);
lines.push(""); // blank line
lines.push(`*Total page views:* ${pageViews}`);
lines.push(`*Unique days visited:* ${uniqueDaysCount}`);
lines.push(""); // blank line
// List the days
if (days.length > 0) {
lines.push(`*Visit history by day:*`);
for (const day of days) {
lines.push(`• *${day}*`);
const urls = daysMap[day];
urls.forEach((url) => {
lines.push(` - ${url}`);
});
}
} else {
lines.push(`_No page history available_`);
}
const slack_text = lines.join("\n");
return [
{
slack_text
}
];
3. Slack Node: Send Slack Message About Returning Visitor
Message Type: Simple Text Message
Message Text:
={{ $json.slack_text }}Channel: your chosen alert channel (e.g.,
rb2b_n8n_alerts)Use Markdown: Off (simple Slack bold/italics still work)
This sends an immediate alert to your team whenever a visitor returns to your site on a new day.
Optional: Add a "time between visits" threshold
You may only want alerts when someone comes back after a meaningful gap, for example more than 7 days between their first visit and their latest visit.
You can add that as a second condition to Check if returning over multiple days.
Updated IF logic
Edit your Check if returning over multiple days node and use an expression that combines both checks:
{{
$json.unique_days_count > 1 &&
(
(new Date($json.last_seen) - new Date($json.first_seen)) /
(1000 * 60 * 60 * 24)
) > 7
}}Operator: is true
This expression does two things:
unique_days_count > 1Confirms the visitor has been on your site across more than one unique calendar day.
(new Date(last_seen) - new Date(first_seen)) / (1000 * 60 * 60 * 24) > 7Calculates the number of days between the first and latest visit.
Only passes if the difference is greater than 7 days.
You can change 7 to any threshold that makes sense for your team, for example 1 for at least one day apart, 30 for long term return visitors, and so on.
With this in place, Slack alerts are sent only when:
The visitor has visited on more than one unique day, and
At least 7 days have passed between their first visit and their most recent visit.





