{
"name": "SaaS Churn Prevention System",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 9 * * *"
}
]
}
},
"id": "daily-health-check",
"name": "Daily Health Check",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.1,
"position": [240, 400]
},
{
"parameters": {
"authentication": "oAuth2Api",
"resource": "table",
"operation": "read",
"application": "appYOUR_AIRTABLE_APP_ID",
"table": "Customers",
"options": {
"filterByFormula": "AND({Status} = 'Active', {ChurnRisk} = '')"
}
},
"id": "get-active-customers",
"name": "Get Active Customers",
"type": "n8n-nodes-base.airtable",
"typeVersion": 2,
"position": [460, 400]
},
{
"parameters": {
"url": "<https://api.stripe.com/v1/customers/>{{ $json.fields.StripeCustomerID }}/subscriptions",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer {{ $vars.stripe_api_key }}"
}
]
}
},
"id": "get-billing-data",
"name": "Get Billing Data",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [680, 300]
},
{
"parameters": {
"url": "<https://api.mixpanel.com/api/2.0/engage?project_id=>{{ $vars.mixpanel_project_id }}&distinct_id={{ $json.fields.UserID }}",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Basic {{ $vars.mixpanel_api_secret }}"
}
]
}
},
"id": "get-usage-data",
"name": "Get Product Usage Data",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [680, 400]
},
{
"parameters": {
"url": "<https://api.intercom.io/conversations/search>",
"requestMethod": "POST",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"options": {
"bodyContentType": "json"
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "{\"query\": {\"field\": \"contact_ids\", \"operator\": \"=\", \"value\": \"{{ $json.fields.IntercomContactID }}\"}}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer {{ $vars.intercom_access_token }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"id": "get-support-data",
"name": "Get Support Tickets",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [680, 500]
},
{
"parameters": {
"jsCode": "// Aggregate all customer data\nconst customer = $('Get Active Customers').first().json.fields;\nconst billing = $('Get Billing Data').first().json;\nconst usage = $('Get Product Usage Data').first().json;\nconst support = $('Get Support Tickets').first().json;\n\n// Calculate usage metrics\nconst lastLoginDays = usage.results?.[0]?.properties?.last_seen \n ? Math.floor((Date.now() - new Date(usage.results[0].properties.last_seen).getTime()) / (1000 * 60 * 60 * 24))\n : 999;\n\nconst loginFrequency = usage.results?.[0]?.properties?.login_count_30d || 0;\nconst featureUsage = usage.results?.[0]?.properties?.feature_adoption_percent || 0;\n\n// Calculate billing metrics\nconst paymentFailures = billing.data?.[0]?.payment_settings?.payment_method_options?.failures || 0;\nconst mrr = billing.data?.[0]?.plan?.amount ? billing.data[0].plan.amount / 100 : 0;\nconst daysUntilRenewal = billing.data?.[0]?.current_period_end \n ? Math.floor((billing.data[0].current_period_end * 1000 - Date.now()) / (1000 * 60 * 60 * 24))\n : 365;\n\n// Calculate support metrics\nconst supportTickets30d = support.conversations?.length || 0;\nconst openTickets = support.conversations?.filter(c => c.state === 'open')?.length || 0;\n\n// Usage Score (0-40 points)\nlet usageScore = 0;\nif (lastLoginDays <= 7) usageScore += 40;\nelse if (lastLoginDays <= 14) usageScore += 30;\nelse if (lastLoginDays <= 30) usageScore += 20;\nelse if (lastLoginDays <= 60) usageScore += 10;\n\nif (loginFrequency >= 20) usageScore += 0; // Bonus already in base\nelse if (loginFrequency >= 10) usageScore -= 5;\nelse if (loginFrequency >= 5) usageScore -= 10;\nelse usageScore -= 20;\n\nif (featureUsage >= 60) usageScore += 0;\nelse if (featureUsage >= 40) usageScore -= 5;\nelse if (featureUsage >= 20) usageScore -= 10;\nelse usageScore -= 15;\n\n// Engagement Score (0-30 points)\nlet engagementScore = 30;\nif (supportTickets30d > 5) engagementScore -= 10;\nif (openTickets > 2) engagementScore -= 10;\n\n// Business Score (0-20 points)\nlet businessScore = 20;\nif (paymentFailures > 0) businessScore -= 10;\nif (daysUntilRenewal < 30) businessScore -= 5;\n\n// Sentiment Score (0-10 points) - simplified\nlet sentimentScore = 10;\nif (supportTickets30d > 3) sentimentScore -= 5;\n\n// Total Health Score (0-100)\nconst healthScore = Math.max(0, Math.min(100, usageScore + engagementScore + businessScore + sentimentScore));\n\n// Churn Risk Score (inverse of health, 0-10)\nconst churnRisk = Math.round((100 - healthScore) / 10);\n\n// Determine risk tier\nlet riskTier;\nif (churnRisk >= 0 && churnRisk <= 3) riskTier = 'Low';\nelse if (churnRisk >= 4 && churnRisk <= 6) riskTier = 'Medium';\nelse if (churnRisk >= 7 && churnRisk <= 8) riskTier = 'High';\nelse riskTier = 'Critical';\n\n// Identify risk factors\nconst riskFactors = [];\nif (lastLoginDays > 14) riskFactors.push('Inactive user');\nif (loginFrequency < 10) riskFactors.push('Low login frequency');\nif (featureUsage < 40) riskFactors.push('Low feature adoption');\nif (paymentFailures > 0) riskFactors.push('Payment issues');\nif (supportTickets30d > 3) riskFactors.push('High support volume');\nif (daysUntilRenewal < 60) riskFactors.push('Renewal approaching');\n\nreturn [{\n json: {\n customerID: customer.CustomerID,\n customerName: customer.Name,\n email: customer.Email,\n mrr: mrr,\n healthScore: healthScore,\n churnRisk: churnRisk,\n riskTier: riskTier,\n riskFactors: riskFactors.join(', '),\n lastLoginDays: lastLoginDays,\n loginFrequency: loginFrequency,\n featureUsage: featureUsage,\n supportTickets: supportTickets30d,\n paymentFailures: paymentFailures,\n daysUntilRenewal: daysUntilRenewal,\n timestamp: new Date().toISOString()\n }\n}];"
},
"id": "calculate-churn-risk",
"name": "Calculate Churn Risk Score",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [900, 400]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "at-risk-check",
"leftValue": "={{ $json.churnRisk }}",
"rightValue": "4",
"operator": {
"type": "number",
"operation": "gte"
}
}
]
}
},
"id": "at-risk-filter",
"name": "At-Risk Customer Filter",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [1120, 400]
},
{
"parameters": {
"authentication": "oAuth2Api",
"resource": "table",
"operation": "update",
"application": "appYOUR_AIRTABLE_APP_ID",
"table": "Customers",
"id": "={{ $('Get Active Customers').first().json.id }}",
"columns": {
"mappingMode": "defineBelow",
"value": {
"HealthScore": "={{ $json.healthScore }}",
"ChurnRisk": "={{ $json.churnRisk }}",
"RiskTier": "={{ $json.riskTier }}",
"RiskFactors": "={{ $json.riskFactors }}",
"LastChecked": "={{ $json.timestamp }}",
"LastLoginDays": "={{ $json.lastLoginDays }}",
"FeatureAdoption": "={{ $json.featureUsage }}"
}
}
},
"id": "update-customer-health",
"name": "Update Customer Health Score",
"type": "n8n-nodes-base.airtable",
"typeVersion": 2,
"position": [1340, 300]
},
{
"parameters": {
"model": "gpt-4",
"options": {
"temperature": 0.4,
"maxTokens": 600
},
"messages": {
"values": [
{
"role": "system",
"content": "You are a customer success AI analyzing churn risk. Provide specific, actionable intervention recommendations based on customer data."
},
{
"role": "user",
"content": "Analyze this at-risk SaaS customer and recommend intervention:\n\nCustomer: {{ $json.customerName }}\nMRR: ${{ $json.mrr }}\nChurn Risk: {{ $json.churnRisk }}/10\nRisk Tier: {{ $json.riskTier }}\nHealth Score: {{ $json.healthScore }}/100\n\nKey Metrics:\n- Last login: {{ $json.lastLoginDays }} days ago\n- Login frequency: {{ $json.loginFrequency }} times/month\n- Feature adoption: {{ $json.featureUsage }}%\n- Support tickets: {{ $json.supportTickets }} in last 30 days\n- Days until renewal: {{ $json.daysUntilRenewal }}\n\nRisk Factors: {{ $json.riskFactors }}\n\nProvide:\n1. PRIMARY_CONCERN: [Main issue]\n2. INTERVENTION_TYPE: [automated/human/executive]\n3. RECOMMENDED_ACTION: [Specific next step]\n4. MESSAGE_TONE: [supportive/educational/urgent]\n5. SUCCESS_METRIC: [What to track]"
}
]
}
},
"id": "ai-intervention-strategy",
"name": "AI Intervention Strategy",
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 1.3,
"position": [1340, 400]
},
{
"parameters": {
"jsCode": "const analysis = $input.first().json.choices[0].message.content;\nconst customer = $('Calculate Churn Risk Score').first().json;\n\n// Parse AI recommendations\nconst concernMatch = analysis.match(/PRIMARY_CONCERN:\\s*(.+?)(?=\\n|$)/i);\nconst interventionMatch = analysis.match(/INTERVENTION_TYPE:\\s*(\\w+)/i);\nconst actionMatch = analysis.match(/RECOMMENDED_ACTION:\\s*(.+?)(?=\\n|$)/i);\nconst toneMatch = analysis.match(/MESSAGE_TONE:\\s*(\\w+)/i);\nconst metricMatch = analysis.match(/SUCCESS_METRIC:\\s*(.+?)(?=\\n|$)/i);\n\nreturn [{\n json: {\n ...customer,\n aiConcern: concernMatch ? concernMatch[1].trim() : 'Engagement declining',\n interventionType: interventionMatch ? interventionMatch[1].trim() : 'automated',\n recommendedAction: actionMatch ? actionMatch[1].trim() : 'Send re-engagement email',\n messageTone: toneMatch ? toneMatch[1].trim() : 'supportive',\n successMetric: metricMatch ? metricMatch[1].trim() : 'Login frequency',\n fullAnalysis: analysis\n }\n}];"
},
"id": "parse-ai-recommendations",
"name": "Parse AI Recommendations",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [1560, 400]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "tier-routing",
"leftValue": "={{ $json.riskTier }}",
"rightValue": "Low,Medium",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
}
},
"id": "route-by-risk-tier",
"name": "Route by Risk Tier",
"type": "n8n-nodes-base.switch",
"typeVersion": 3,
"position": [1780, 400]
},
{
"parameters": {
"fromEmail": "success@yourcompany.com",
"toEmail": "={{ $json.email }}",
"subject": "We noticed you haven't been active lately - here's how we can help",
"emailFormat": "html",
"html": "<html>\n<body style=\"font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 600px; margin: 0 auto;\">\n\n<div style=\"background: #f8f9fa; padding: 30px; text-align: center;\">\n <h2 style=\"color: #007bff; margin: 0;\">Hey {{ $json.customerName.split(' ')[0] }}, we miss you! 👋</h2>\n</div>\n\n<div style=\"padding: 30px;\">\n <p>I noticed you haven't logged into [Product] in the last {{ $json.lastLoginDays }} days, and I wanted to personally reach out.</p>\n \n <p><strong>Is everything okay?</strong> Sometimes our customers get busy or hit a roadblock, and we're here to help.</p>\n \n <div style=\"background: #e7f3ff; padding: 20px; border-radius: 8px; margin: 20px 0;\">\n <h3 style=\"color: #007bff; margin-top: 0;\">Quick Wins to Get Back on Track:</h3>\n <ul style=\"margin: 0; padding-left: 20px;\">\n <li style=\"margin-bottom: 10px;\">✅ Check out our new [Feature] - it could save you 2 hours/week</li>\n <li style=\"margin-bottom: 10px;\">📚 Watch this 5-minute tutorial on getting more value</li>\n <li style=\"margin-bottom: 10px;\">💬 Book a 15-min call with me to discuss your goals</li>\n </ul>\n </div>\n \n <p><strong>Your current adoption: {{ $json.featureUsage }}%</strong><br>\n Most successful customers are at 60%+ - let's get you there!</p>\n \n <div style=\"text-align: center; margin: 30px 0;\">\n <a href=\"<https://yourapp.com/dashboard\>" style=\"background: #007bff; color: white; padding: 15px 30px; text-decoration: none; border-radius: 5px; display: inline-block; font-weight: bold;\">Jump Back In →</a>\n </div>\n \n <p>Or simply reply to this email - I read every response personally.</p>\n \n <p>Best regards,<br>\n [Your Name]<br>\n Customer Success Team</p>\n</div>\n\n<div style=\"background: #f8f9fa; padding: 20px; text-align: center; font-size: 14px; color: #6c757d;\">\n <p style=\"margin: 0;\">P.S. If you're too busy right now, no worries! Just let me know when would be a better time to connect.</p>\n</div>\n\n</body>\n</html>"
},
"id": "send-automated-reengagement",
"name": "Send Automated Re-engagement",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2.1,
"position": [2000, 300]
},
{
"parameters": {
"url": "{{ $vars.slack_webhook_url }}",
"options": {
"bodyContentType": "json"
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "{\n \"text\": \"🚨 High-Risk Customer Alert\",\n \"blocks\": [\n {\n \"type\": \"header\",\n \"text\": {\n \"type\": \"plain_text\",\n \"text\": \"🚨 HIGH-RISK CUSTOMER - IMMEDIATE ACTION NEEDED\"\n }\n },\n {\n \"type\": \"section\",\n \"fields\": [\n {\n \"type\": \"mrkdwn\",\n \"text\": \"*Customer:* {{ $json.customerName }}\"\n },\n {\n \"type\": \"mrkdwn\",\n \"text\": \"*MRR:* ${{ $json.mrr }}\"\n },\n {\n \"type\": \"mrkdwn\",\n \"text\": \"*Churn Risk:* {{ $json.churnRisk }}/10 🔥\"\n },\n {\n \"type\": \"mrkdwn\",\n \"text\": \"*Health Score:* {{ $json.healthScore }}/100\"\n },\n {\n \"type\": \"mrkdwn\",\n \"text\": \"*Last Login:* {{ $json.lastLoginDays }} days ago\"\n },\n {\n \"type\": \"mrkdwn\",\n \"text\": \"*Renewal:* {{ $json.daysUntilRenewal }} days\"\n }\n ]\n },\n {\n \"type\": \"section\",\n \"text\": {\n \"type\": \"mrkdwn\",\n \"text\": \"*🎯 AI Analysis:*\\n{{ $json.aiConcern }}\"\n }\n },\n {\n \"type\": \"section\",\n \"text\": {\n \"type\": \"mrkdwn\",\n \"text\": \"*⚠️ Risk Factors:*\\n{{ $json.riskFactors }}\"\n }\n },\n {\n \"type\": \"section\",\n \"text\": {\n \"type\": \"mrkdwn\",\n \"text\": \"*💡 Recommended Action:*\\n{{ $json.recommendedAction }}\"\n }\n },\n {\n \"type\": \"actions\",\n \"elements\": [\n {\n \"type\": \"button\",\n \"text\": {\n \"type\": \"plain_text\",\n \"text\": \"📞 Schedule Call\"\n },\n \"style\": \"primary\",\n \"url\": \"<https://calendly.com/your-team\>"\n },\n {\n \"type\": \"button\",\n \"text\": {\n \"type\": \"plain_text\",\n \"text\": \"📊 View Customer\"\n },\n \"url\": \"<https://yourcrm.com/customers/>{{ $json.customerID }}\"\n },\n {\n \"type\": \"button\",\n \"text\": {\n \"type\": \"plain_text\",\n \"text\": \"✅ I'll Handle This\"\n },\n \"style\": \"default\",\n \"action_id\": \"claim_customer\"\n }\n ]\n },\n {\n \"type\": \"context\",\n \"elements\": [\n {\n \"type\": \"mrkdwn\",\n \"text\": \"⏰ *Action Required:* {{ $json.riskTier }} risk customers need outreach within 24-48 hours\"\n }\n ]\n }\n ]\n}"
},
"id": "alert-cs-team",
"name": "Alert Customer Success Team",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [2000, 500]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict"
},
"conditions": [
{
"id": "critical-check",
"leftValue": "={{ $json.riskTier }}",
"rightValue": "Critical",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
}
},
"id": "critical-escalation",
"name": "Critical Escalation Check",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [2220, 400]
},
{
"parameters": {
"fromEmail": "ceo@yourcompany.com",
"toEmail": "leadership@yourcompany.com",
"cc": "success@yourcompany.com",
"subject": "🚨 CRITICAL: ${{ $json.mrr }}/mo Customer at Risk - {{ $json.customerName }}",
"emailFormat": "html",
"html": "<html>\n<body style=\"font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 700px; margin: 0 auto;\">\n\n<div style=\"background: #dc3545; color: white; padding: 25px; text-align: center;\">\n <h1 style=\"margin: 0; font-size: 24px;\">🚨 CRITICAL CHURN RISK ALERT</h1>\n <p style=\"margin: 10px 0 0 0; font-size: 16px;\">Immediate Executive Intervention Required</p>\n</div>\n\n<div style=\"background: #fff3cd; border-left: 5px solid #ffc107; padding: 20px; margin: 20px 0;\">\n <p style=\"margin: 0; color: #856404; font-weight: bold;\">⚠️ A high-value customer is at critical risk of churning. This requires immediate C-level attention.</p>\n</div>\n\n<div style=\"padding: 20px;\">\n <h3 style=\"color: #dc3545; border-bottom: 2px solid #dc3545; padding-bottom: 10px;\">Customer Details</h3>\n <table style=\"width: 100%; border-collapse: collapse;\">\n <tr style=\"border-bottom: 1px solid #dee2e6;\">\n <td style=\"padding: 12px 0; font-weight: bold; width: 40%;\">Customer:</td>\n <td style=\"padding: 12px 0;\">{{ $json.customerName }}</td>\n </tr>\n <tr style=\"border-bottom: 1px solid #dee2e6;\">\n <td style=\"padding: 12px 0; font-weight: bold;\">Monthly Revenue:</td>\n <td style=\"padding: 12px 0; color: #dc3545; font-size: 18px; font-weight: bold;\">${{ $json.mrr }}</td>\n </tr>\n <tr style=\"border-bottom: 1px solid #dee2e6;\">\n <td style=\"padding: 12px 0; font-weight: bold;\">Churn Risk Score:</td>\n <td style=\"padding: 12px 0; color: #dc3545; font-weight: bold;\">{{ $json.churnRisk }}/10 (CRITICAL)</td>\n </tr>\n <tr style=\"border-bottom: 1px solid #dee2e6;\">\n <td style=\"padding: 12px 0; font-weight: bold;\">Health Score:</td>\n <td style=\"padding: 12px 0;\">{{ $json.healthScore }}/100</td>\n </tr>\n <tr style=\"border-bottom: 1px solid #dee2e6;\">\n <td style=\"padding: 12px 0; font-weight: bold;\">Last Active:</td>\n <td style=\"padding: 12px 0;\">{{ $json.lastLoginDays }} days ago</td>\n </tr>\n <tr>\n <td style=\"padding: 12px 0; font-weight: bold;\">Contract Renewal:</td>\n <td style=\"padding: 12px 0;\">{{ $json.daysUntilRenewal }} days</td>\n </tr>\n </table>\n\n <h3 style=\"color: #495057; border-bottom: 2px solid #007bff; padding-bottom: 10px; margin-top: 30px;\">🔍 AI Analysis</h3>\n <div style=\"background: #f8f9fa; padding: 15px; border-radius: 5px;\">\n <p style=\"margin: 0;\"><strong>Primary Concern:</strong> {{ $json.aiConcern }}</p>\n </div>\n\n <h3 style=\"color: #495057; border-bottom: 2px solid #ffc107; padding-bottom: 10px; margin-top: 30px;\">⚠️ Risk Factors</h3>\n <div style=\"background: #fff3cd; padding: 15px; border-radius: 5px; border-left: 4px solid #ffc107;\">\n <p style=\"margin: 0;\">{{ $json.riskFactors }}</p>\n </div>\n\n <h3 style=\"color: #495057; border-bottom: 2px solid #28a745; padding-bottom: 10px; margin-top: 30px;\">💡 Recommended Intervention</h3>\n <div style=\"background: #d4edda; padding: 15px; border-radius: 5px; border-left: 4px solid #28a745;\">\n <p style=\"margin: 0;\">{{ $json.recommendedAction }}</p>\n </div>\n\n <div style=\"background: #dc3545; color: white; padding: 20px; border-radius: 8px; margin: 30px 0; text-align: center;\">\n <h3 style=\"margin: 0 0 15px 0;\">⏰ URGENT ACTION REQUIRED</h3>\n <p style=\"margin: 0; font-size: 18px; font-weight: bold;\">Executive outreach needed within 24 hours</p>\n <p style=\"margin: 10px 0 0 0;\">Potential Revenue at Risk: ${{ $json.mrr * 12 }}/year</p>\n </div>\n\n <div style=\"text-align: center; margin: 30px 0;\">\n <a href=\"<https://calendly.com/leadership-calls\>" style=\"background: #007bff; color: white; padding: 15px 30px; text-decoration: none; border-radius: 5px; display: inline-block; margin-right: 15px; font-weight: bold;\">📞 Schedule Executive Call</a>\n <a href=\"<https://yourcrm.com/customers/>{{ $json.customerID }}\" style=\"background: #28a745; color: white; padding: 15px 30px; text-decoration: none; border-radius: 5px; display: inline-block; font-weight: bold;\">📊 View Full Customer Profile</a>\n </div>\n\n <div style=\"background: #e7f3ff; padding: 15px; border-radius: 5px; margin-top: 20px;\">\n <h4 style=\"margin: 0 0 10px 0; color: #0066cc;\">📋 Immediate Action Checklist:</h4>\n <ul style=\"margin: 0; padding-left: 20px; color: #495057;\">\n <li>□ Review customer usage patterns and goals</li>\n <li>□ Schedule executive-level call within 24 hours</li>\n <li>□ Prepare custom retention offer</li>\n <li>□ Identify root cause of disengagement</li>\n <li>□ Develop win-back strategy</li>\n </ul>\n </div>\n</div>\n\n<div style=\"background: #f8f9fa; padding: 20px; text-align: center; font-size: 14px; color: #6c757d;\">\n <p style=\"margin: 0;\">This alert was generated automatically by the Churn Prevention System<br>\n Time: {{ $json.timestamp }}</p>\n</div>\n\n</body>\n</html>"
},
"id": "executive-escalation-email",
"name": "Executive Escalation Email",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2.1,
"position": [2440, 300]
},
{
"parameters": {
"resource": "message",
"operation": "sendText",
"chatId": "{{ $vars.telegram_leadership_chat }}",
"text": "🚨 *CRITICAL CHURN ALERT* 🚨\\n\\n*Customer:* {{ $json.customerName }}\\n*MRR at Risk:* ${{ $json.mrr }}/mo (${{ $json.mrr * 12 }}/year)\\n*Churn Risk:* {{ $json.churnRisk }}/10\\n*Last Active:* {{ $json.lastLoginDays }} days ago\\n\\n*Primary Issue:*\\n{{ $json.aiConcern }}\\n\\n*Action Required:*\\nExecutive outreach within 24 hours\\n\\n[View Customer](<https://yourcrm.com/customers/>{{ $json.customerID }})",
"additionalFields": {
"parse_mode": "Markdown"
}
},
"id": "telegram-executive-alert",
"name": "Telegram Executive Alert",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.1,
"position": [2440, 400]
},
{
"parameters": {
"authentication": "oAuth2Api",
"resource": "table",
"operation": "create",
"application": "appYOUR_AIRTABLE_APP_ID",
"table": "Interventions",
"columns": {
"mappingMode": "defineBelow",
"value": {
"CustomerID": "={{ $json.customerID }}",
"CustomerName": "={{ $json.customerName }}",
"InterventionType": "={{ $json.interventionType }}",
"RiskTier": "={{ $json.riskTier }}",
"ChurnRisk": "={{ $json.churnRisk }}",
"RecommendedAction": "={{ $json.recommendedAction }}",
"Timestamp": "={{ $json.timestamp }}",
"Status": "Pending",
"AIAnalysis": "={{ $json.fullAnalysis }}"
}
}
},
"id": "log-intervention",
"name": "Log Intervention",
"type": "n8n-nodes-base.airtable",
"typeVersion": 2,
"position": [2000, 700]
},
{
"parameters": {
"authentication": "oAuth2Api",
"resource": "table",
"operation": "update",
"application": "appYOUR_AIRTABLE_APP_ID",
"table": "Customers",
"id": "={{ $('Get Active Customers').first().json.id }}",
"columns": {
"mappingMode": "defineBelow",
"value": {
"HealthScore": "={{ $json.healthScore }}",
"ChurnRisk": "={{ $json.churnRisk }}",
"RiskTier": "={{ $json.riskTier }}",
"RiskFactors": "={{ $json.riskFactors }}",
"LastChecked": "={{ $json.timestamp }}",
"LastLoginDays": "={{ $json.lastLoginDays }}",
"FeatureAdoption": "={{ $json.featureUsage }}"
}
}
},
"id": "save-healthy-customer",
"name": "Save Healthy Customer Data",
"type": "n8n-nodes-base.airtable",
"typeVersion": 2,
"position": [1340, 600]
}
],
"connections": {
"Daily Health Check": {
"main": [
[
{
"node": "Get Active Customers",
"type": "main",
"index": 0
}
]
]
},
"Get Active Customers": {
"main": [
[
{
"node": "Get Billing Data",
"type": "main",
"index": 0
},
{
"node": "Get Product Usage Data",
"type": "main",
"index": 0
},
{
"node": "Get Support Tickets",
"type": "main",
"index": 0
}
]
]
},
"Get Billing Data": {
"main": [
[
{
"node": "Calculate Churn Risk Score",
"type": "main",
"index": 0
}
]
]
},
"Get Product Usage Data": {
"main": [
[
{
"node": "Calculate Churn Risk Score",
"type": "main",
"index": 0
}
]
]
},
"Get Support Tickets": {
"main": [
[
{
"node": "Calculate Churn Risk Score",
"type": "main",
"index": 0
}
]
]
},
"Calculate Churn Risk Score": {
"main": [
[
{
"node": "At-Risk Customer Filter",
"type": "main",
"index": 0
}
]
]
},
"At-Risk Customer Filter": {
"main": [
[
{
"node": "Update Customer Health Score",
"type": "main",
"index": 0
},
{
"node": "AI Intervention Strategy",
"type": "main",
"index": 0
}
],
[
{
"node": "Save Healthy Customer Data",
"type": "main",
"index": 0
}
]
]
},
"AI Intervention Strategy": {
"main": [
[
{
"node": "Parse AI Recommendations",
"type": "main",
"index": 0
}
]
]
},
"Parse AI Recommendations": {
"main": [
[
{
"node": "Route by Risk Tier",
"type": "main",
"index": 0
},
{
"node": "Log Intervention",
"type": "main",
"index": 0
}
]
]
},
"Route by Risk Tier": {
"main": [
[
{
"node": "Send Automated Re-engagement",
"type": "main",
"index": 0
}
],
[
{
"node": "Alert Customer Success Team",
"type": "main",
"index": 0
},
{
"node": "Critical Escalation Check",
"type": "main",
"index": 0
}
]
]
},
"Critical Escalation Check": {
"main": [
[
{
"node": "Executive Escalation Email",
"type": "main",
"index": 0
},
{
"node": "Telegram Executive Alert",
"type": "main",
"index": 0
}
]
]
}
},
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"staticData": {},
"tags": [],
"triggerCount": 0,
"updatedAt": "2025-01-01T12:00:00.000Z",
"versionId": "1"
}