Un onboarding eficient al clientilor stimuleaza retentia si satisfactia. Acest ghid arata cum sa construiesti automatizari complete de onboarding cu n8n pentru experiente fluide ale clientilor.
Arhitectura workflow-ului de onboarding
Handler trigger client nou
// n8n Function Node - New Customer Processor
const webhookData = $input.first().json;
// Validate incoming customer data
const requiredFields = ['email', 'name', 'plan'];
const missingFields = requiredFields.filter(f => !webhookData[f]);
if (missingFields.length > 0) {
throw new Error(`Missing required fields: ${missingFields.join(', ')}`);
}
// Normalize and enrich customer data
const customer = {
id: webhookData.customer_id || `cust_${Date.now()}`,
email: webhookData.email.toLowerCase().trim(),
firstName: extractFirstName(webhookData.name),
lastName: extractLastName(webhookData.name),
fullName: webhookData.name,
company: webhookData.company || null,
plan: webhookData.plan,
planTier: determinePlanTier(webhookData.plan),
source: webhookData.source || 'website',
signupDate: new Date().toISOString(),
timezone: webhookData.timezone || 'UTC',
locale: webhookData.locale || 'en',
metadata: {
utm_source: webhookData.utm_source,
utm_medium: webhookData.utm_medium,
utm_campaign: webhookData.utm_campaign,
referrer: webhookData.referrer
}
};
// Determine onboarding path
const onboardingPath = determineOnboardingPath(customer);
function extractFirstName(fullName) {
return fullName.split(' ')[0];
}
function extractLastName(fullName) {
const parts = fullName.split(' ');
return parts.length > 1 ? parts.slice(1).join(' ') : '';
}
function determinePlanTier(plan) {
const tiers = {
'starter': 'basic',
'professional': 'standard',
'business': 'premium',
'enterprise': 'enterprise'
};
return tiers[plan.toLowerCase()] || 'basic';
}
function determineOnboardingPath(customer) {
// Clientii enterprise primesc onboarding personalizat
if (customer.planTier === 'enterprise') {
return {
type: 'enterprise',
steps: ['sales_handoff', 'kickoff_call', 'custom_setup', 'training', 'go_live'],
assignedCSM: true,
duration: '30_days'
};
}
// Premium primeste onboarding ghidat
if (customer.planTier === 'premium') {
return {
type: 'guided',
steps: ['welcome', 'setup_wizard', 'demo_call', 'training_videos', 'check_in'],
assignedCSM: false,
duration: '14_days'
};
}
// Onboarding self-service standard
return {
type: 'self_service',
steps: ['welcome', 'setup_wizard', 'email_sequence', 'in_app_guides'],
assignedCSM: false,
duration: '7_days'
};
}
return {
json: {
customer,
onboarding: {
path: onboardingPath,
startedAt: new Date().toISOString(),
currentStep: 0,
completedSteps: [],
status: 'started'
}
}
};Workflow de provizionare utilizatori
// n8n Function Node - Account Provisioning
const { customer, onboarding } = $input.first().json;
// Generate secure credentials
const provisioning = {
customerId: customer.id,
accountId: `acc_${generateSecureId()}`,
apiKey: `sk_live_${generateSecureId(32)}`,
webhookSecret: `whsec_${generateSecureId(24)}`,
tempPassword: generateTempPassword(),
passwordResetToken: generateSecureId(48),
tokenExpiry: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString() // 24 ore
};
// Determine initial setup based on plan
const initialSetup = {
features: getFeaturesByPlan(customer.plan),
limits: getLimitsByPlan(customer.plan),
defaults: getDefaultSettings(customer.planTier),
integrations: []
};
// Create provisioning tasks
const tasks = [
{
type: 'create_account',
data: {
accountId: provisioning.accountId,
email: customer.email,
name: customer.fullName,
plan: customer.plan
}
},
{
type: 'create_api_credentials',
data: {
accountId: provisioning.accountId,
apiKey: provisioning.apiKey,
webhookSecret: provisioning.webhookSecret
}
},
{
type: 'setup_initial_config',
data: initialSetup
},
{
type: 'create_sample_data',
data: {
accountId: provisioning.accountId,
templates: getSampleTemplates(customer.planTier)
}
}
];
function generateSecureId(length = 16) {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < length; i++) {
result += chars.charAt(Math.floor(Math.random() * chars.length));
}
return result;
}
function generateTempPassword() {
const upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const lower = 'abcdefghijklmnopqrstuvwxyz';
const numbers = '0123456789';
const special = '!@#$%^&*';
let password = '';
password += upper.charAt(Math.floor(Math.random() * upper.length));
password += lower.charAt(Math.floor(Math.random() * lower.length));
password += numbers.charAt(Math.floor(Math.random() * numbers.length));
password += special.charAt(Math.floor(Math.random() * special.length));
const allChars = upper + lower + numbers + special;
for (let i = 0; i < 8; i++) {
password += allChars.charAt(Math.floor(Math.random() * allChars.length));
}
return password.split('').sort(() => Math.random() - 0.5).join('');
}
function getFeaturesByPlan(plan) {
const features = {
starter: ['basic_dashboard', 'email_support', 'api_access'],
professional: ['advanced_analytics', 'priority_support', 'api_access', 'integrations'],
business: ['custom_reports', 'dedicated_support', 'advanced_api', 'sso', 'audit_logs'],
enterprise: ['all_features', 'custom_development', 'sla', 'dedicated_infrastructure']
};
return features[plan.toLowerCase()] || features.starter;
}
function getLimitsByPlan(plan) {
const limits = {
starter: { users: 5, storage_gb: 10, api_calls_monthly: 10000 },
professional: { users: 25, storage_gb: 100, api_calls_monthly: 100000 },
business: { users: 100, storage_gb: 500, api_calls_monthly: 500000 },
enterprise: { users: -1, storage_gb: -1, api_calls_monthly: -1 } // Nelimitat
};
return limits[plan.toLowerCase()] || limits.starter;
}
function getDefaultSettings(tier) {
return {
notifications: { email: true, in_app: true, slack: tier !== 'basic' },
security: { mfa_required: tier === 'enterprise', session_timeout: 3600 },
privacy: { analytics_enabled: true, crash_reports: true }
};
}
function getSampleTemplates(tier) {
const templates = ['getting_started', 'basic_workflow'];
if (tier !== 'basic') {
templates.push('advanced_automation', 'reporting_template');
}
if (tier === 'enterprise') {
templates.push('enterprise_integration', 'compliance_workflow');
}
return templates;
}
return {
json: {
customer,
onboarding,
provisioning,
tasks
}
};Secventa de email-uri de bun venit
// n8n Function Node - Email Sequence Builder
const { customer, onboarding, provisioning } = $input.first().json;
// Build personalized email sequence
const emailSequence = [];
// Ziua 0 - Email de bun venit
emailSequence.push({
day: 0,
hours: 0,
template: 'welcome',
subject: `Welcome to ${process.env.COMPANY_NAME}, ${customer.firstName}!`,
personalization: {
firstName: customer.firstName,
plan: customer.plan,
loginUrl: `${process.env.APP_URL}/login`,
passwordResetUrl: `${process.env.APP_URL}/reset-password?token=${provisioning.passwordResetToken}`,
supportEmail: process.env.SUPPORT_EMAIL
},
tags: ['onboarding', 'day_0', 'welcome']
});
// Ziua 1 - Ghid de inceput
emailSequence.push({
day: 1,
hours: 10, // Trimite la ora 10 in fusul orar al clientului
template: 'getting_started',
subject: `Get started with ${process.env.COMPANY_NAME} in 5 minutes`,
personalization: {
firstName: customer.firstName,
quickStartUrl: `${process.env.APP_URL}/quickstart`,
videoTutorialUrl: `${process.env.DOCS_URL}/tutorials/getting-started`,
features: getTopFeatures(customer.plan)
},
tags: ['onboarding', 'day_1', 'education'],
condition: {
type: 'not_completed',
milestone: 'first_login'
}
});
// Ziua 3 - Prezentare functionalitate
emailSequence.push({
day: 3,
hours: 14,
template: 'feature_spotlight',
subject: `Did you know? ${getFeatureSpotlight(customer.plan).title}`,
personalization: {
firstName: customer.firstName,
feature: getFeatureSpotlight(customer.plan),
cta_url: `${process.env.APP_URL}/features/${getFeatureSpotlight(customer.plan).slug}`
},
tags: ['onboarding', 'day_3', 'feature'],
condition: {
type: 'not_used',
feature: getFeatureSpotlight(customer.plan).slug
}
});
// Ziua 5 - Sugestii de integrari
if (customer.planTier !== 'basic') {
emailSequence.push({
day: 5,
hours: 10,
template: 'integrations',
subject: `Connect ${process.env.COMPANY_NAME} to your favorite tools`,
personalization: {
firstName: customer.firstName,
suggestedIntegrations: getSuggestedIntegrations(customer),
integrationsUrl: `${process.env.APP_URL}/integrations`
},
tags: ['onboarding', 'day_5', 'integrations']
});
}
// Ziua 7 - Verificare
emailSequence.push({
day: 7,
hours: 10,
template: 'check_in',
subject: `How's it going, ${customer.firstName}?`,
personalization: {
firstName: customer.firstName,
usageStats: '{{usage_stats}}', // Placeholder pentru date dinamice
feedbackUrl: `${process.env.APP_URL}/feedback`,
bookCallUrl: onboarding.path.type !== 'self_service' ?
`${process.env.CALENDLY_URL}/onboarding-call` : null
},
tags: ['onboarding', 'day_7', 'engagement']
});
// Ziua 14 - Sfaturi de succes (pentru onboarding ghidat)
if (onboarding.path.type !== 'self_service') {
emailSequence.push({
day: 14,
hours: 10,
template: 'success_tips',
subject: `Pro tips for ${customer.plan} users`,
personalization: {
firstName: customer.firstName,
tips: getProTips(customer.planTier),
communityUrl: `${process.env.COMMUNITY_URL}`,
webinarUrl: `${process.env.APP_URL}/webinars`
},
tags: ['onboarding', 'day_14', 'education']
});
}
function getTopFeatures(plan) {
const features = {
starter: [
{ name: 'Dashboard', description: 'Vezi toate datele tale dintr-o privire' },
{ name: 'Reports', description: 'Genereaza rapoarte de baza' }
],
professional: [
{ name: 'Advanced Analytics', description: 'Analizeaza in profunzime metricile tale' },
{ name: 'Integrations', description: 'Conecteaza instrumentele tale preferate' }
],
business: [
{ name: 'Custom Reports', description: 'Construieste rapoarte dupa nevoile tale' },
{ name: 'Team Collaboration', description: 'Lucreaza eficient in echipa' }
],
enterprise: [
{ name: 'SSO', description: 'Autentificare unica securizata' },
{ name: 'Audit Logs', description: 'Urmarire completa a activitatii' }
]
};
return features[plan.toLowerCase()] || features.starter;
}
function getFeatureSpotlight(plan) {
const spotlights = {
starter: { title: 'Automated Reminders', slug: 'reminders', description: 'Nu mai rata taskuri importante' },
professional: { title: 'Workflow Automation', slug: 'workflows', description: 'Automatizeaza taskurile repetitive' },
business: { title: 'Custom Dashboards', slug: 'dashboards', description: 'Construieste vizualizarea perfecta' },
enterprise: { title: 'API Access', slug: 'api', description: 'Construieste integrari personalizate' }
};
return spotlights[plan.toLowerCase()] || spotlights.starter;
}
function getSuggestedIntegrations(customer) {
// Ar fi bazat pe industria/cazul de utilizare al clientului
return [
{ name: 'Slack', icon: 'slack', description: 'Primeste notificari in Slack' },
{ name: 'Google Calendar', icon: 'google-calendar', description: 'Sincronizeaza programul tau' },
{ name: 'Zapier', icon: 'zapier', description: 'Conecteaza 3000+ aplicatii' }
];
}
function getProTips(tier) {
return [
'Foloseste scurtaturi de tastatura pentru navigare mai rapida',
'Configureaza rezumate saptamanale prin email pentru actualizari de echipa',
'Creeaza template-uri pentru taskurile frecvente'
];
}
// Calculeaza orele de trimitere
const scheduledEmails = emailSequence.map(email => {
const sendDate = new Date(customer.signupDate);
sendDate.setDate(sendDate.getDate() + email.day);
sendDate.setHours(email.hours, 0, 0, 0);
return {
...email,
scheduledAt: sendDate.toISOString(),
recipientEmail: customer.email,
recipientName: customer.fullName,
customerId: customer.id
};
});
return {
json: {
customer,
onboarding,
emailSequence: scheduledEmails
}
};Urmarire progres
// n8n Function Node - Onboarding Progress Tracker
const customer = $input.first().json.customer;
const currentProgress = $('Get Current Progress').first()?.json || {};
// Defineste milestone-urile de onboarding
const milestones = {
self_service: [
{ id: 'account_created', name: 'Cont creat', weight: 10 },
{ id: 'first_login', name: 'Prima autentificare', weight: 15 },
{ id: 'profile_completed', name: 'Profil completat', weight: 10 },
{ id: 'first_project', name: 'Primul proiect creat', weight: 20 },
{ id: 'invited_team', name: 'Membru echipa invitat', weight: 15 },
{ id: 'used_core_feature', name: 'Functionalitate principala folosita', weight: 20 },
{ id: 'completed_tutorial', name: 'Tutorial finalizat', weight: 10 }
],
guided: [
{ id: 'account_created', name: 'Cont creat', weight: 5 },
{ id: 'first_login', name: 'Prima autentificare', weight: 10 },
{ id: 'profile_completed', name: 'Profil completat', weight: 5 },
{ id: 'demo_completed', name: 'Apel demo finalizat', weight: 15 },
{ id: 'first_project', name: 'Primul proiect creat', weight: 15 },
{ id: 'integration_setup', name: 'Integrare configurata', weight: 15 },
{ id: 'invited_team', name: 'Echipa invitata', weight: 15 },
{ id: 'training_completed', name: 'Training finalizat', weight: 20 }
],
enterprise: [
{ id: 'kickoff_completed', name: 'Apel kickoff finalizat', weight: 10 },
{ id: 'requirements_gathered', name: 'Cerinte colectate', weight: 10 },
{ id: 'environment_setup', name: 'Mediu configurat', weight: 15 },
{ id: 'sso_configured', name: 'SSO configurat', weight: 10 },
{ id: 'data_migration', name: 'Migrare date completa', weight: 15 },
{ id: 'team_training', name: 'Training echipa complet', weight: 15 },
{ id: 'pilot_launched', name: 'Pilot lansat', weight: 10 },
{ id: 'go_live', name: 'Go Live complet', weight: 15 }
]
};
// Ia milestone-urile relevante pentru client
const customerMilestones = milestones[currentProgress.onboardingType] || milestones.self_service;
// Calculeaza progresul
const completedMilestones = currentProgress.completedMilestones || [];
const completedWeight = customerMilestones
.filter(m => completedMilestones.includes(m.id))
.reduce((sum, m) => sum + m.weight, 0);
const progressPercentage = Math.round(completedWeight);
// Determina pasul curent
const pendingMilestones = customerMilestones.filter(m => !completedMilestones.includes(m.id));
const nextMilestone = pendingMilestones[0];
// Calculeaza scorul de sanatate
const healthScore = calculateHealthScore(customer, currentProgress);
// Determina daca este nevoie de interventie
const intervention = checkForIntervention(customer, currentProgress, healthScore);
function calculateHealthScore(customer, progress) {
let score = 100;
// Zile de la inregistrare
const daysSinceSignup = Math.floor(
(Date.now() - new Date(customer.signupDate).getTime()) / (1000 * 60 * 60 * 24)
);
// Penalizeaza progresul lent
const expectedProgress = Math.min(daysSinceSignup * 10, 70); // Asteapta ~70% pana in ziua 7
const actualProgress = progressPercentage;
if (actualProgress < expectedProgress) {
score -= (expectedProgress - actualProgress);
}
// Penalizeaza lipsa activitatii recente
const lastActivity = progress.lastActivityAt ?
Math.floor((Date.now() - new Date(progress.lastActivityAt).getTime()) / (1000 * 60 * 60 * 24)) : daysSinceSignup;
if (lastActivity > 3) {
score -= (lastActivity - 3) * 5;
}
// Bonus pentru actiuni cheie
if (completedMilestones.includes('invited_team')) score += 10;
if (completedMilestones.includes('integration_setup')) score += 10;
return Math.max(0, Math.min(100, score));
}
function checkForIntervention(customer, progress, healthScore) {
const interventions = [];
// Scor de sanatate scazut
if (healthScore < 50) {
interventions.push({
type: 'low_health',
action: 'personal_outreach',
priority: 'high',
message: 'Clientul poate avea nevoie de asistenta'
});
}
// Fara autentificare dupa 48 de ore
if (!progress.completedMilestones?.includes('first_login')) {
const hoursSinceSignup = (Date.now() - new Date(customer.signupDate).getTime()) / (1000 * 60 * 60);
if (hoursSinceSignup > 48) {
interventions.push({
type: 'no_login',
action: 'reminder_email',
priority: 'medium',
message: 'Clientul nu s-a autentificat'
});
}
}
// Blocat la un anumit milestone
if (progress.stalledAt) {
interventions.push({
type: 'stalled_progress',
action: 'help_content',
priority: 'medium',
milestone: progress.stalledAt,
message: `Clientul este blocat la ${progress.stalledAt}`
});
}
return interventions;
}
// Construieste raportul de progres
const progressReport = {
customerId: customer.id,
email: customer.email,
plan: customer.plan,
onboardingType: currentProgress.onboardingType || 'self_service',
startedAt: customer.signupDate,
lastActivityAt: currentProgress.lastActivityAt,
progress: {
percentage: progressPercentage,
completedMilestones: completedMilestones,
pendingMilestones: pendingMilestones.map(m => m.id),
nextMilestone: nextMilestone,
totalMilestones: customerMilestones.length
},
healthScore: healthScore,
interventionsNeeded: intervention,
status: progressPercentage >= 100 ? 'completed' :
progressPercentage >= 50 ? 'on_track' :
healthScore < 50 ? 'at_risk' : 'in_progress',
generatedAt: new Date().toISOString()
};
return { json: progressReport };Ghiduri personalizate in aplicatie
// n8n Function Node - In-App Guide Builder
const customer = $input.first().json;
const userBehavior = $('Get User Behavior').first()?.json || {};
// Defineste template-uri de ghiduri
const guideTemplates = {
welcome_tour: {
id: 'welcome_tour',
name: 'Tur de bun venit',
type: 'product_tour',
steps: [
{
target: '#dashboard',
title: 'Dashboard-ul tau',
content: 'Aici vei vedea toate metricile importante dintr-o privire.',
position: 'bottom'
},
{
target: '#create-button',
title: 'Creeaza primul tau proiect',
content: 'Apasa aici pentru a incepe primul proiect. Te vom ghida prin proces.',
position: 'right'
},
{
target: '#settings-menu',
title: 'Personalizeaza experienta',
content: 'Acceseaza setarile pentru a personaliza spatiul de lucru.',
position: 'left'
}
],
trigger: 'first_login',
dismissible: true
},
feature_discovery: {
id: 'feature_discovery',
name: 'Descoperire functionalitati',
type: 'tooltip_sequence',
steps: [
{
target: '#analytics-tab',
title: 'Analytics',
content: 'Analizeaza in profunzime datele tale cu analytics avansat.',
position: 'bottom',
condition: { plan_tier: ['standard', 'premium', 'enterprise'] }
},
{
target: '#automations',
title: 'Automatizari',
content: 'Configureaza workflow-uri automatizate pentru a economisi timp.',
position: 'right'
}
],
trigger: 'milestone_completed',
milestone: 'first_project'
},
empty_state_prompt: {
id: 'empty_state_prompt',
name: 'Prompt de inceput',
type: 'modal',
content: {
title: 'Sa incepem!',
body: 'Creeaza primul proiect pentru a debloca potentialul complet al platformei.',
cta_text: 'Creeaza proiect',
cta_action: 'open_create_modal',
secondary_text: 'Vezi tutorial',
secondary_action: 'open_tutorial'
},
trigger: 'empty_state',
entity: 'projects'
},
integration_prompt: {
id: 'integration_prompt',
name: 'Sugestie integrari',
type: 'banner',
content: {
title: 'Conecteaza instrumentele tale',
body: 'Integreaza cu aplicatiile preferate pentru a eficientiza workflow-ul.',
cta_text: 'Vezi integrari',
cta_action: 'navigate_integrations'
},
trigger: 'time_in_app',
threshold_minutes: 30,
condition: { integrations_count: 0 }
},
upgrade_prompt: {
id: 'upgrade_prompt',
name: 'Prompt upgrade',
type: 'modal',
content: {
title: 'Deblocheaza mai multe functionalitati',
body: 'Folosesti {{usage_percentage}}% din limitele planului tau. Fa upgrade pentru mai mult.',
features: ['Proiecte nelimitate', 'Analytics avansat', 'Suport prioritar'],
cta_text: 'Vezi planuri',
cta_action: 'navigate_pricing'
},
trigger: 'usage_threshold',
threshold: 80
}
};
// Determina ce ghiduri sa afiseze pe baza starii utilizatorului
function selectGuidesForUser(customer, behavior) {
const selectedGuides = [];
const now = new Date();
const signupDate = new Date(customer.signupDate);
const daysSinceSignup = Math.floor((now - signupDate) / (1000 * 60 * 60 * 24));
// Prima autentificare - afiseaza turul de bun venit
if (behavior.loginCount <= 1 && !behavior.completedGuides?.includes('welcome_tour')) {
selectedGuides.push({
...guideTemplates.welcome_tour,
priority: 1,
reason: 'Prima autentificare'
});
}
// Dupa primul proiect - afiseaza descoperire functionalitati
if (behavior.projectsCreated >= 1 && !behavior.completedGuides?.includes('feature_discovery')) {
const guide = guideTemplates.feature_discovery;
// Filtreaza pasii pe baza planului
guide.steps = guide.steps.filter(step => {
if (!step.condition) return true;
if (step.condition.plan_tier) {
return step.condition.plan_tier.includes(customer.planTier);
}
return true;
});
selectedGuides.push({
...guide,
priority: 2,
reason: 'Primul proiect finalizat'
});
}
// Stare goala - indeamna la creare
if (behavior.projectsCreated === 0 && daysSinceSignup >= 1) {
selectedGuides.push({
...guideTemplates.empty_state_prompt,
priority: 1,
reason: 'Niciun proiect dupa 24 de ore'
});
}
// Prompt integrari dupa timp petrecut in aplicatie
if (behavior.totalMinutesInApp >= 30 &&
behavior.integrationsCount === 0 &&
!behavior.dismissedGuides?.includes('integration_prompt')) {
selectedGuides.push({
...guideTemplates.integration_prompt,
priority: 3,
reason: 'Nicio integrare dupa 30 de minute'
});
}
// Prompt upgrade la pragul de utilizare
if (behavior.usagePercentage >= 80 && customer.planTier !== 'enterprise') {
const guide = { ...guideTemplates.upgrade_prompt };
guide.content.body = guide.content.body.replace('{{usage_percentage}}', behavior.usagePercentage);
selectedGuides.push({
...guide,
priority: 2,
reason: 'Utilizare ridicata'
});
}
return selectedGuides.sort((a, b) => a.priority - b.priority);
}
// Personalizeaza continutul ghidului
function personalizeGuide(guide, customer) {
const personalized = JSON.parse(JSON.stringify(guide));
// Inlocuieste placeholder-urile
const replacements = {
'{{firstName}}': customer.firstName,
'{{company}}': customer.company || 'echipa ta',
'{{plan}}': customer.plan
};
const contentStr = JSON.stringify(personalized);
let personalizedContent = contentStr;
for (const [placeholder, value] of Object.entries(replacements)) {
personalizedContent = personalizedContent.replace(new RegExp(placeholder, 'g'), value);
}
return JSON.parse(personalizedContent);
}
const selectedGuides = selectGuidesForUser(customer, userBehavior);
const personalizedGuides = selectedGuides.map(guide => personalizeGuide(guide, customer));
return {
json: {
customerId: customer.id,
guides: personalizedGuides,
behavior: userBehavior,
generatedAt: new Date().toISOString()
}
};Finalizare si predare
// n8n Function Node - Onboarding Completion Handler
const progressReport = $input.first().json;
// Verifica daca onboarding-ul este complet
const isComplete = progressReport.progress.percentage >= 100;
const isTimedOut = checkOnboardingTimeout(progressReport);
// Determina pasii urmatori
function determineNextSteps(report) {
if (isComplete) {
return {
action: 'complete_onboarding',
tasks: [
{ type: 'send_completion_email', template: 'onboarding_complete' },
{ type: 'update_customer_stage', stage: 'active' },
{ type: 'trigger_nps_survey', delay_days: 7 },
{ type: 'schedule_success_call', condition: 'premium_or_higher' }
]
};
}
if (isTimedOut) {
return {
action: 'escalate_stalled',
tasks: [
{ type: 'notify_csm', priority: 'high' },
{ type: 'send_reengagement_email', template: 'stuck_onboarding' },
{ type: 'create_support_ticket', reason: 'Onboarding blocat' }
]
};
}
if (report.interventionsNeeded.length > 0) {
return {
action: 'intervention_required',
tasks: report.interventionsNeeded.map(i => ({
type: `handle_${i.type}`,
...i
}))
};
}
return {
action: 'continue_monitoring',
tasks: []
};
}
function checkOnboardingTimeout(report) {
const maxDays = {
self_service: 14,
guided: 30,
enterprise: 60
};
const daysSinceStart = Math.floor(
(Date.now() - new Date(report.startedAt).getTime()) / (1000 * 60 * 60 * 24)
);
const timeout = maxDays[report.onboardingType] || 14;
return daysSinceStart > timeout && report.progress.percentage < 100;
}
// Construieste raportul de finalizare
const completionReport = {
customerId: progressReport.customerId,
email: progressReport.email,
plan: progressReport.plan,
onboardingType: progressReport.onboardingType,
finalStatus: isComplete ? 'completed' : isTimedOut ? 'timed_out' : 'in_progress',
completionPercentage: progressReport.progress.percentage,
healthScore: progressReport.healthScore,
completedMilestones: progressReport.progress.completedMilestones,
pendingMilestones: progressReport.progress.pendingMilestones,
timeToComplete: isComplete ? calculateTimeToComplete(progressReport) : null,
nextSteps: determineNextSteps(progressReport),
recommendations: generateRecommendations(progressReport),
reportedAt: new Date().toISOString()
};
function calculateTimeToComplete(report) {
const start = new Date(report.startedAt);
const end = new Date();
return Math.floor((end - start) / (1000 * 60 * 60 * 24)); // zile
}
function generateRecommendations(report) {
const recommendations = [];
if (report.progress.percentage < 50) {
recommendations.push({
type: 'engagement',
message: 'Ia in considerare o abordare personalizata pentru a imbunatati engagement-ul'
});
}
if (!report.progress.completedMilestones.includes('invited_team')) {
recommendations.push({
type: 'expansion',
message: 'Incurajeaza invitatiile in echipa pentru o adoptie mai buna'
});
}
if (report.healthScore < 70) {
recommendations.push({
type: 'support',
message: 'Se recomanda un apel proactiv de suport'
});
}
return recommendations;
}
return { json: completionReport };Bune practici
Design de onboarding
- Personalizeaza pe segment: Clienti diferiti au nevoie de fluxuri de onboarding diferite
- Urmareste milestone-urile: Defineste metrici clare de succes pentru fiecare etapa de onboarding
- Intervino devreme: Monitorizeaza scorurile de sanatate si actioneaza inainte ca clientii sa plece
- Itereaza continuu: Imbunatateste pe baza ratelor de finalizare si a feedback-ului
Sfaturi de automatizare
- Foloseste secvente de email conditionate pe baza actiunilor utilizatorului
- Implementeaza pauze inteligente intre punctele de contact
- Combina ghiduri in aplicatie cu email pentru engagement pe mai multe canale
- Urmareste fiecare interactiune pentru optimizare
Onboarding-ul automatizat cu n8n asigura experiente consistente si personalizate care contribuie la succesul si retentia clientilor.
Sistemul tau AI e conform cu EU AI Act? Evaluare gratuita de risc - afla in 2 minute →