This workflow corresponds to n8n.io template #4454 — we link there as the canonical source.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "3lIutQSsxmpnS38v",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "BeyondPresence Sales Opportunity Scoring - Real-Time Lead Intelligence",
"tags": [],
"nodes": [
{
"id": "8131b77c-66b2-4138-bac9-1062dd50b631",
"name": "Workflow Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
80,
-600
],
"parameters": {
"color": 6,
"width": 560,
"height": 660,
"content": "## \ud83c\udfaf Sales Opportunity Scoring System\n\n**What This Does:**\n- Monitors BeyondPresence user messages in real-time\n- Scores leads based on buying signals\n- Detects competitor mentions instantly\n- Estimates potential deal size\n- Sends intelligent alerts to Slack\n\n**Setup Required:**\n1. Configure Slack OAuth2 credentials\n2. Update channel names in Slack nodes\n3. Add BeyondPresence webhook URL"
},
"typeVersion": 1
},
{
"id": "ab3a8f0b-a1ab-4f88-80ed-435115915cb3",
"name": "Scoring Rules",
"type": "n8n-nodes-base.stickyNote",
"position": [
680,
-600
],
"parameters": {
"color": 4,
"width": 400,
"height": 780,
"content": "## \ud83d\udcca Scoring Logic\n\n**Buying Signals (+Points):**\n- \"interested\" / \"tell me more\" (+20)\n- \"budget\" / \"pricing\" (+15)\n- \"timeline\" / \"when\" (+15)\n- \"demo\" / \"trial\" (+25)\n- \"decision maker\" (+30)\n- \"purchase\" / \"buy\" (+30)\n\n**Negative Signals (-Points):**\n- \"too expensive\" (-20)\n- \"not interested\" (-30)\n- \"just looking\" (-15)\n- \"maybe later\" (-10)"
},
"typeVersion": 1
},
{
"id": "6395e121-1f83-4d07-a8e2-1566c37511ce",
"name": "Alert System",
"type": "n8n-nodes-base.stickyNote",
"position": [
1100,
-600
],
"parameters": {
"color": 3,
"width": 380,
"height": 780,
"content": "## \ud83d\udd14 Slack Alerts\n\n**Automatic Notifications:**\n- \ud83d\udd25 Hot leads (score > 70)\n- \u26a1 Competitor mentions\n- \ud83d\udcb0 Large deal indicators\n- \ud83d\udcc8 Buying signal clusters\n- \ud83d\udea8 At-risk opportunities\n\n**Smart Threading:**\n- Groups messages by call ID\n- Shows conversation context\n- Tracks score progression"
},
"typeVersion": 1
},
{
"id": "abc9e5e4-df53-4891-97ff-6c18fd06d534",
"name": "BeyondPresence Real-Time Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
100,
-120
],
"parameters": {
"path": "beyondpresence-sales-intelligence",
"options": {
"rawBody": false
},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2
},
{
"id": "f94cb19d-0bca-4f42-8f25-11cc853f3323",
"name": "Acknowledge Receipt",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
280,
-120
],
"parameters": {
"options": {
"responseCode": 200
},
"respondWith": "json",
"responseBody": "{\n \"status\": \"success\",\n \"message\": \"Sales intelligence processing\",\n \"timestamp\": \"{{ $now.toISO() }}\"\n}"
},
"typeVersion": 1.2
},
{
"id": "9dae992f-6930-4db1-9c18-b85deaa352df",
"name": "Filter User Messages",
"type": "n8n-nodes-base.switch",
"position": [
460,
-120
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "user_message",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.body.event_type }}",
"rightValue": "message"
},
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.body.message.sender }}",
"rightValue": "user"
}
]
},
"renameOutput": true
},
{
"outputKey": "call_ended",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.body.event_type }}",
"rightValue": "call_ended"
}
]
},
"renameOutput": true
}
]
},
"options": {
"fallbackOutput": "none"
}
},
"typeVersion": 3.2
},
{
"id": "c7cc875b-4282-4197-9d56-879a287fe385",
"name": "Score Sales Opportunity",
"type": "n8n-nodes-base.code",
"position": [
720,
-160
],
"parameters": {
"jsCode": "// Sales Opportunity Scoring Engine\n// Helper function for recommendations (moved to top for better organization)\nfunction generateRecommendations(score, signals) {\n const recommendations = [];\n \n if (score >= 70) {\n recommendations.push('\ud83d\udcde Schedule immediate follow-up call');\n recommendations.push('\ud83d\udc64 Loop in senior sales rep');\n recommendations.push('\ud83d\udcca Prepare custom pricing proposal');\n } else if (score >= 40) {\n recommendations.push('\ud83d\udce7 Send detailed product information');\n recommendations.push('\ud83d\udcc5 Offer demo scheduling link');\n recommendations.push('\ud83d\udcda Share relevant case studies');\n } else if (score < 0) {\n recommendations.push('\ud83c\udfaf Address specific objections');\n recommendations.push('\ud83d\udca1 Focus on value proposition');\n recommendations.push('\ud83d\udcde Schedule follow-up for better timing');\n }\n \n if (signals.includes('\ud83c\udfc1 Competitor Evaluation')) {\n recommendations.push('\u2694\ufe0f Prepare competitive differentiation materials');\n }\n \n return recommendations;\n}\n\ntry {\n // Safely extract input data with validation\n const input = $input.first();\n if (!input || !input.json || !input.json.body) {\n throw new Error('Invalid input structure');\n }\n \n const messageData = input.json.body;\n const message = messageData.message;\n const callId = messageData.call_id || 'unknown';\n const userName = messageData.call_data?.userName || 'Unknown User';\n \n // Validate message structure\n if (!message || !message.message) {\n throw new Error('Message content is missing');\n }\n \n // Initialize scoring\n let opportunityScore = 0;\n const detectedSignals = [];\n const alerts = [];\n \n // Buying Signal Detection with Scoring\n const buyingSignals = {\n high_intent: {\n keywords: ['purchase', 'buy', 'implement', 'contract', 'agreement', 'sign up', 'ready to move forward'],\n score: 30,\n label: '\ud83d\udd25 High Purchase Intent'\n },\n decision_maker: {\n keywords: ['decision maker', 'my team', 'our company', 'we need', 'our budget', 'my boss', 'approval from'],\n score: 25,\n label: '\ud83d\udc54 Decision Maker Indicator'\n },\n demo_request: {\n keywords: ['demo', 'trial', 'test', 'try it', 'see it in action', 'show me', 'walk through'],\n score: 25,\n label: '\ud83d\udda5\ufe0f Demo Request'\n },\n timeline: {\n keywords: ['when can', 'how soon', 'timeline', 'start date', 'implement by', 'deadline', 'need this by'],\n score: 20,\n label: '\u23f0 Timeline Discussion'\n },\n budget: {\n keywords: ['budget', 'cost', 'pricing', 'investment', 'roi', 'pay', 'afford', 'price point'],\n score: 15,\n label: '\ud83d\udcb0 Budget Discussion'\n },\n interest: {\n keywords: ['interested', 'tell me more', 'sounds good', 'like this', 'impressive', 'exactly what', 'perfect'],\n score: 15,\n label: '\ud83d\udc4d Positive Interest'\n },\n problem_fit: {\n keywords: ['solve our problem', 'exactly what we need', 'perfect for us', 'this would help', 'addresses our'],\n score: 20,\n label: '\u2705 Strong Problem-Solution Fit'\n }\n };\n \n // Negative Signal Detection\n const negativeSignals = {\n price_objection: {\n keywords: ['too expensive', 'cant afford', 'over budget', 'too much', 'cheaper option', 'cost too high'],\n score: -25,\n label: '\ud83d\udcb8 Price Objection'\n },\n not_interested: {\n keywords: ['not interested', 'no thanks', 'not for us', 'pass', 'not looking', 'don\\'t need'],\n score: -30,\n label: '\u274c Not Interested'\n },\n timing: {\n keywords: ['not right now', 'maybe later', 'next year', 'not a priority', 'down the road', 'future'],\n score: -15,\n label: '\u23f8\ufe0f Bad Timing'\n },\n just_browsing: {\n keywords: ['just looking', 'researching', 'comparing options', 'early stages', 'exploring', 'window shopping'],\n score: -10,\n label: '\ud83d\udd0d Just Browsing'\n }\n };\n \n // Competitor Detection \n const competitors = [\n 'competitor', 'alternative', 'other options', 'shopping around',\n 'comparing', 'versus', 'instead of', 'switch from',\n // Competitor Detection - Add your specific competitors here\n 'competitor1', 'competitor2'\n ];\n \n // Deal Size Indicators\n const dealSizeIndicators = {\n enterprise: {\n keywords: ['enterprise', 'company-wide', 'global', 'multiple teams', 'thousand users', 'all departments', 'entire organization'],\n multiplier: 10,\n label: '\ud83c\udfe2 Enterprise Deal'\n },\n mid_market: {\n keywords: ['department', 'team of', 'hundred users', 'multiple locations', 'division', 'several teams'],\n multiplier: 5,\n label: '\ud83c\udfec Mid-Market Deal'\n },\n small_business: {\n keywords: ['small team', 'few users', 'startup', 'small business', 'just us', 'handful of people'],\n multiplier: 1,\n label: '\ud83c\udfea Small Business Deal'\n }\n };\n \n // Process message through scoring engine\n const messageLower = message.message.toLowerCase();\n \n // Check buying signals\n Object.entries(buyingSignals).forEach(([key, signal]) => {\n if (signal.keywords.some(keyword => messageLower.includes(keyword))) {\n opportunityScore += signal.score;\n detectedSignals.push(signal.label);\n }\n });\n \n // Check negative signals\n Object.entries(negativeSignals).forEach(([key, signal]) => {\n if (signal.keywords.some(keyword => messageLower.includes(keyword))) {\n opportunityScore += signal.score; // Note: score is negative\n detectedSignals.push(signal.label);\n alerts.push(`\u26a0\ufe0f Objection Detected: ${signal.label}`);\n }\n });\n \n // Check for competitors\n const mentionedCompetitors = competitors.filter(comp => \n messageLower.includes(comp.toLowerCase())\n );\n if (mentionedCompetitors.length > 0) {\n alerts.push(`\ud83c\udfaf Competitor Mentioned: ${mentionedCompetitors.join(', ')}`);\n detectedSignals.push('\ud83c\udfc1 Competitor Evaluation');\n }\n \n // Estimate deal size\n let dealSizeEstimate = 'standard';\n let dealMultiplier = 2;\n Object.entries(dealSizeIndicators).forEach(([size, indicator]) => {\n if (indicator.keywords.some(keyword => messageLower.includes(keyword))) {\n dealSizeEstimate = size;\n dealMultiplier = indicator.multiplier;\n detectedSignals.push(indicator.label);\n }\n });\n \n // Determine lead temperature\n let leadTemperature = '\ud83e\uddca Cold';\n let alertUrgency = 'low';\n if (opportunityScore >= 70) {\n leadTemperature = '\ud83d\udd25 Hot';\n alertUrgency = 'high';\n alerts.push('\ud83d\udea8 HOT LEAD DETECTED!');\n } else if (opportunityScore >= 40) {\n leadTemperature = '\ud83c\udf21\ufe0f Warm';\n alertUrgency = 'medium';\n } else if (opportunityScore >= 20) {\n leadTemperature = '\ud83d\ude0e Cool';\n alertUrgency = 'low';\n }\n \n // Extract numbers for deal size estimation - Improved regex\n const numberMatches = messageLower.match(/\\$?\\d{1,3}(?:,\\d{3})*(?:\\.\\d{2})?[km]?|\\d+[km]/gi);\n let estimatedValue = null;\n if (numberMatches && numberMatches.length > 0) {\n // Convert to standardized number\n const lastNumber = numberMatches[numberMatches.length - 1];\n let parsedValue = 0;\n \n if (lastNumber.toLowerCase().includes('k')) {\n parsedValue = parseFloat(lastNumber.replace(/[^0-9.]/g, '')) * 1000;\n } else if (lastNumber.toLowerCase().includes('m')) {\n parsedValue = parseFloat(lastNumber.replace(/[^0-9.]/g, '')) * 1000000;\n } else {\n parsedValue = parseFloat(lastNumber.replace(/[$,]/g, ''));\n }\n \n // Only set estimatedValue if we got a valid number\n if (!isNaN(parsedValue) && parsedValue > 0) {\n estimatedValue = parsedValue * dealMultiplier;\n }\n }\n \n // Prepare output\n return [{\n json: {\n // Message context\n callId: callId,\n userName: userName,\n timestamp: message.sent_at || new Date().toISOString(),\n sender: message.sender || 'unknown',\n message: message.message,\n \n // Scoring results\n opportunityScore: opportunityScore,\n leadTemperature: leadTemperature,\n alertUrgency: alertUrgency,\n \n // Detected signals\n detectedSignals: detectedSignals,\n alerts: alerts,\n \n // Competitor intelligence\n competitorsMentioned: mentionedCompetitors,\n hasCompetitorMention: mentionedCompetitors.length > 0,\n \n // Deal estimation\n dealSizeCategory: dealSizeEstimate,\n dealMultiplier: dealMultiplier,\n estimatedDealValue: estimatedValue,\n formattedDealValue: estimatedValue ? `$${estimatedValue.toLocaleString()}` : 'Not detected',\n \n // Action recommendations\n recommendedActions: generateRecommendations(opportunityScore, detectedSignals),\n \n // Metadata\n processedAt: new Date().toISOString(),\n workflowExecution: $execution?.id || 'unknown',\n \n // Success indicator\n success: true,\n error: null\n }\n }];\n \n} catch (error) {\n // Return error response\n return [{\n json: {\n success: false,\n error: error.message,\n callId: 'error',\n userName: 'Unknown',\n timestamp: new Date().toISOString(),\n opportunityScore: 0,\n leadTemperature: '\u274c Error',\n alertUrgency: 'high',\n alerts: [`\ud83d\udea8 Processing Error: ${error.message}`],\n recommendedActions: ['\ud83d\udd27 Check input data format', '\ud83d\udcde Contact technical support'],\n processedAt: new Date().toISOString()\n }\n }];\n}"
},
"typeVersion": 2
},
{
"id": "88281417-5a4a-414d-9c8f-295ac1b3aeaa",
"name": "Route Alerts",
"type": "n8n-nodes-base.switch",
"position": [
920,
-200
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "hot_lead",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.alertUrgency }}",
"rightValue": "high"
}
]
},
"renameOutput": true
},
{
"outputKey": "competitor_alert",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.hasCompetitorMention }}",
"rightValue": "={{ true }}"
}
]
},
"renameOutput": true
},
{
"outputKey": "qualified_lead",
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "number",
"operation": "gte"
},
"leftValue": "={{ $json.opportunityScore }}",
"rightValue": 40
}
]
},
"renameOutput": true
}
]
},
"options": {
"fallbackOutput": "none"
}
},
"typeVersion": 3.2
},
{
"id": "0f6ed4eb-c8d4-4c1e-8c03-991d887c83f9",
"name": "Slack: Hot Lead Alert",
"type": "n8n-nodes-base.slack",
"position": [
1260,
-260
],
"parameters": {
"text": "=\ud83d\udd25 *HOT LEAD ALERT!*\n\n*Lead:* {{ $json.userName }}\n*Score:* {{ $json.opportunityScore }} {{ $json.leadTemperature }}\n*Call ID:* `{{ $json.callId }}`\n\n*Message:* _\"{{ $json.message }}\"_\n\n*Detected Signals:*\n{{ $json.detectedSignals.join('\\n') }}\n\n*Recommended Actions:*\n{{ $json.recommendedActions.join('\\n') }}\n\n{{ $json.estimatedDealValue ? `\ud83d\udcb0 *Estimated Deal Value:* ${$json.formattedDealValue}` : '' }}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "name",
"value": "#sales-hot-leads"
},
"otherOptions": {
"mrkdwn": true
},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "35d57ba3-432e-444a-bde4-b6bc5a340ee7",
"name": "Slack: Competitor Alert",
"type": "n8n-nodes-base.slack",
"position": [
1240,
-120
],
"parameters": {
"text": "=\ud83c\udfaf *Competitor Intelligence Alert*\n\n*Lead:* {{ $json.userName }}\n*Competitors Mentioned:* `{{ $json.competitorsMentioned.join(', ') }}`\n\n*Context:* _\"{{ $json.message }}\"_\n\n*Current Lead Score:* {{ $json.opportunityScore }} {{ $json.leadTemperature }}\n\n*Recommended Response:*\n\u2694\ufe0f Emphasize unique differentiators\n\ud83d\udcca Share competitive comparison docs\n\ud83c\udfaf Address specific competitor weaknesses",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "name",
"value": "#sales-competitors"
},
"otherOptions": {
"mrkdwn": true
},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "6ddcb61a-dc4d-4585-b0e2-e7c62eba7b3f",
"name": "Slack: Qualified Lead",
"type": "n8n-nodes-base.slack",
"position": [
1240,
20
],
"parameters": {
"text": "=\ud83d\udcc8 *Qualified Lead Update*\n\n*Lead:* {{ $json.userName }}\n*Score:* {{ $json.opportunityScore }} {{ $json.leadTemperature }}\n\n*Latest Message:* _\"{{ $json.message }}\"_\n\n*Buying Signals:*\n{{ $json.detectedSignals.filter(s => !s.includes('\u274c') && !s.includes('\ud83d\udcb8') && !s.includes('\u23f8\ufe0f') && !s.includes('\ud83d\udd0d')).join('\\n') || 'None detected' }}\n\n*Next Steps:*\n{{ $json.recommendedActions.slice(0, 3).join('\\n') }}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "name",
"value": "#sales-qualified"
},
"otherOptions": {
"mrkdwn": true
},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "9efb26ba-abeb-48e3-ad95-e7a14c32ee34",
"name": "Process Call Summary",
"type": "n8n-nodes-base.code",
"position": [
720,
20
],
"parameters": {
"jsCode": "// Process end-of-call summary with final scoring\nconst callData = $input.first().json.body;\nconst messages = callData.messages || [];\n\n// Aggregate scoring across entire conversation\nlet totalScore = 0;\nconst allSignals = new Set();\nconst competitorMentions = new Set();\nlet maxDealValue = 0;\nlet userMessageCount = 0;\n\n// Process each message\nmessages.forEach(msg => {\n if (msg.sender === 'user') {\n userMessageCount++;\n const msgLower = msg.message.toLowerCase();\n \n // Check buying signals\n const buyingKeywords = [\n { keyword: 'interested', score: 15 },\n { keyword: 'budget', score: 15 },\n { keyword: 'timeline', score: 20 },\n { keyword: 'demo', score: 25 },\n { keyword: 'trial', score: 25 },\n { keyword: 'purchase', score: 30 },\n { keyword: 'implement', score: 30 },\n { keyword: 'decision maker', score: 25 },\n { keyword: 'our team', score: 20 }\n ];\n \n buyingKeywords.forEach(item => {\n if (msgLower.includes(item.keyword)) {\n totalScore += item.score;\n allSignals.add(`\u2705 ${item.keyword}`);\n }\n });\n \n // Check negative signals\n const negativeKeywords = [\n { keyword: 'not interested', score: -30 },\n { keyword: 'too expensive', score: -25 },\n { keyword: 'maybe later', score: -15 },\n { keyword: 'just looking', score: -10 }\n ];\n \n negativeKeywords.forEach(item => {\n if (msgLower.includes(item.keyword)) {\n totalScore += item.score;\n allSignals.add(`\u274c ${item.keyword}`);\n }\n });\n \n // Check competitors\n const competitors = ['competitor', 'alternative', 'versus', 'comparing'];\n competitors.forEach(comp => {\n if (msgLower.includes(comp)) {\n competitorMentions.add(comp);\n }\n });\n }\n});\n\n// Calculate final metrics\nconst avgMessageScore = userMessageCount > 0 ? totalScore / userMessageCount : 0;\nconst qualificationLevel = \n totalScore >= 100 ? '\ud83c\udfc6 Highly Qualified' :\n totalScore >= 50 ? '\u2705 Qualified' :\n totalScore >= 20 ? '\ud83e\udd14 Needs Nurturing' :\n '\u2744\ufe0f Not Qualified';\n\nreturn [{\n json: {\n callId: callData.call_id,\n userName: callData.call_data.userName,\n duration: callData.evaluation?.duration_minutes || 0,\n totalMessages: messages.length,\n userMessages: userMessageCount,\n finalScore: totalScore,\n averageScore: avgMessageScore.toFixed(1),\n qualificationLevel: qualificationLevel,\n uniqueSignals: Array.from(allSignals),\n competitorsMentioned: Array.from(competitorMentions),\n callSummary: {\n topic: callData.evaluation?.topic || 'General Discussion',\n sentiment: callData.evaluation?.user_sentiment || 'neutral',\n endTime: callData.call_data.endedAt\n },\n recommendations: generateFinalRecommendations(totalScore, allSignals),\n nextBestAction: totalScore >= 50 ? '\ud83d\udcde Call within 24 hours' : '\ud83d\udce7 Add to nurture campaign'\n }\n}];\n\nfunction generateFinalRecommendations(score, signals) {\n const recs = [];\n if (score >= 100) {\n recs.push('\ud83c\udfaf Fast-track to sales manager');\n recs.push('\ud83d\udcc4 Prepare contract immediately');\n recs.push('\ud83d\udcb0 Custom pricing proposal needed');\n } else if (score >= 50) {\n recs.push('\ud83d\udce7 Send personalized follow-up within 2 hours');\n recs.push('\ud83d\udcc5 Schedule next meeting this week');\n recs.push('\ud83d\udcca Prepare ROI calculation');\n } else {\n recs.push('\ud83c\udf31 Add to nurture campaign');\n recs.push('\ud83d\udcda Send educational content');\n recs.push('\u23f0 Check back in 30 days');\n }\n return recs;\n}"
},
"typeVersion": 2
},
{
"id": "86d700e6-027d-4771-b749-30ad2573bd34",
"name": "Slack: Call Summary",
"type": "n8n-nodes-base.slack",
"position": [
920,
20
],
"parameters": {
"text": "=\ud83d\udcca *Call Summary Report*\n\n*Lead:* {{ $json.userName }}\n*Call Duration:* {{ $json.duration }} minutes\n*Messages:* {{ $json.userMessages }} from user / {{ $json.totalMessages }} total\n\n*Final Qualification:* {{ $json.qualificationLevel }}\n*Total Score:* {{ $json.finalScore }} (Avg: {{ $json.averageScore }}/message)\n\n*Key Signals Detected:*\n{{ $json.uniqueSignals.join('\\n') || 'No strong signals detected' }}\n\n*Competitors Mentioned:* {{ $json.competitorsMentioned.length > 0 ? $json.competitorsMentioned.join(', ') : 'None' }}\n\n*Next Best Action:* {{ $json.nextBestAction }}\n\n*Recommendations:*\n{{ $json.recommendations.join('\\n') }}\n\n---\n_Call ID: `{{ $json.callId }}` | Ended: {{ $json.callSummary.endTime }}_",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "name",
"value": "#sales-summaries"
},
"otherOptions": {
"mrkdwn": true
},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "786595a2-20fc-4948-89da-918fc08d6b1d",
"name": "Setup Instructions",
"type": "n8n-nodes-base.stickyNote",
"position": [
1500,
-500
],
"parameters": {
"width": 340,
"height": 540,
"content": "## \ud83d\udd27 Configuration Steps\n\n**1. Slack OAuth2 Setup:**\n- Go to Credentials \u2192 New\n- Select \"Slack OAuth2 API\"\n- Follow OAuth flow\n- Grant channel write permissions\n\n**2. Update Channel Names:**\n- Hot Leads \n- Competitors \n- Qualified\n- Summaries\n\n**3. Customize Competitors:**\n- Edit \"Score Sales Opportunity\"\n- Add your competitor names\n- Adjust scoring weights\n\n**4. Test Webhook:**\n- Use webhook test URL\n- Send sample user message"
},
"typeVersion": 1
}
],
"active": true,
"settings": {
"executionOrder": "v1"
},
"versionId": "a83151b3-1111-41e2-a9f9-b8680f2dd64f",
"connections": {
"Route Alerts": {
"main": [
[
{
"node": "Slack: Hot Lead Alert",
"type": "main",
"index": 0
}
],
[
{
"node": "Slack: Competitor Alert",
"type": "main",
"index": 0
}
],
[
{
"node": "Slack: Qualified Lead",
"type": "main",
"index": 0
}
]
]
},
"Acknowledge Receipt": {
"main": [
[
{
"node": "Filter User Messages",
"type": "main",
"index": 0
}
]
]
},
"Filter User Messages": {
"main": [
[
{
"node": "Score Sales Opportunity",
"type": "main",
"index": 0
}
],
[]
]
},
"Process Call Summary": {
"main": [
[
{
"node": "Slack: Call Summary",
"type": "main",
"index": 0
}
]
]
},
"Score Sales Opportunity": {
"main": [
[
{
"node": "Route Alerts",
"type": "main",
"index": 0
}
]
]
},
"BeyondPresence Real-Time Webhook": {
"main": [
[
{
"node": "Acknowledge Receipt",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
slackOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Monitor BeyondPresence video agent conversations in real-time to automatically score leads (0-100+) based on buying signals and send instant Slack alerts when hot opportunities or competitors are mentioned. This template helps sales teams prioritize leads immediately, never miss…
Source: https://n8n.io/workflows/4454/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This n8n workflow automates the generation of personalized marketing content for events, including emails, social media posts, and advertisements. Leveraging AI, it tailors content based on event deta
AI Lead Qualification & Follow-Up. Uses httpRequest, slack, googleSheets, gmail. Webhook trigger; 18 nodes.
How It Works This workflow automates the real estate lead qualification process by leveraging property data from BatchData. The automation follows these steps: When a new lead is received through your
IP Enrichment & Country Attribution is a lightweight cybersecurity automation that enriches IP addresses with geographic and network intelligence. It validates incoming IPs, filters out private or inv
Real estate leads move fast. Manually matching buyer requirements with available properties, sending details, updating CRM records, and notifying sales teams often causes delays and missed opportuniti