Live Session Intent Scorer
Real-time Lead Qualification
Advanced behavioral scoring system that analyzes scroll depth, click patterns, time on page, and engagement metrics to provide real-time visitor intent scoring for lead qualification and sales prioritization.
Key Features
Script Overview
What It Does
This advanced script analyzes visitor behavior in real-time to score their purchase or conversion intent. It tracks multiple behavioral signals including scroll depth, time on page, click patterns, and page interactions to provide accurate intent classification.
Use Case
Perfect for sales teams to prioritize leads and trigger personalized outreach based on behavior. Essential for identifying high-intent visitors for immediate follow-up.
Key Benefits
- •Real-time visitor intent scoring
- •Behavioral lead qualification
- •Sales team prioritization data
- •Personalized experience triggers
- •Conversion optimization insights
- •Advanced behavioral analytics
JavaScript Code
<script>
// Live Session Intent Scorer Script
// Version: 1.0
// Last Updated: 2025-09-09
(function() {
'use strict';
var config = {
// Scoring thresholds
thresholds: {
low: 25,
medium: 50,
high: 75
},
// Scoring weights
weights: {
timeOnPage: 25, // 25% weight
scrollDepth: 20, // 20% weight
pageViews: 15, // 15% weight
interactions: 20, // 20% weight
contentEngagement: 20 // 20% weight
},
// High-intent pages (higher scoring)
highIntentPages: [
'/pricing', '/demo', '/trial', '/contact',
'/signup', '/purchase', '/checkout'
],
// High-value interactions
highValueInteractions: [
'video_play', 'download', 'form_start',
'pricing_click', 'demo_request'
],
// Scoring intervals
scoringInterval: 5000, // 5 seconds
// Events
events: {
intentScored: 'session_intent_scored',
intentUpdated: 'intent_score_updated',
highIntent: 'high_intent_detected'
},
debug: false
};
var sessionData = {
startTime: Date.now(),
pageViews: 1,
maxScrollDepth: 0,
totalTimeOnPage: 0,
interactions: 0,
highValueInteractions: 0,
contentEngagementTime: 0,
currentScore: 0,
lastScore: 0,
intentLevel: 'low'
};
var observers = {};
var scoringTimer = null;
function debugLog(message, data) {
if (config.debug) {
console.log('[Intent Scorer] ' + message, data || '');
}
}
function calculateTimeScore() {
var timeOnPage = (Date.now() - sessionData.startTime) / 1000; // seconds
sessionData.totalTimeOnPage = timeOnPage;
// Score based on time thresholds
if (timeOnPage < 30) return 0;
if (timeOnPage < 60) return 20;
if (timeOnPage < 120) return 40;
if (timeOnPage < 300) return 60;
if (timeOnPage < 600) return 80;
return 100;
}
function calculateScrollScore() {
var scrollPercent = getScrollPercentage();
sessionData.maxScrollDepth = Math.max(sessionData.maxScrollDepth, scrollPercent);
// Score based on scroll depth
if (scrollPercent < 25) return 0;
if (scrollPercent < 50) return 30;
if (scrollPercent < 75) return 60;
if (scrollPercent < 90) return 80;
return 100;
}
function calculatePageViewScore() {
// Score based on number of page views
if (sessionData.pageViews === 1) return 20;
if (sessionData.pageViews === 2) return 40;
if (sessionData.pageViews === 3) return 60;
if (sessionData.pageViews >= 4) return 80;
return 100;
}
function calculateInteractionScore() {
var baseInteractions = sessionData.interactions * 10;
var bonusInteractions = sessionData.highValueInteractions * 25;
var totalScore = Math.min(baseInteractions + bonusInteractions, 100);
return totalScore;
}
function calculateContentEngagementScore() {
var engagementRatio = sessionData.contentEngagementTime / sessionData.totalTimeOnPage;
return Math.min(engagementRatio * 100, 100);
}
function calculateOverallScore() {
var timeScore = calculateTimeScore();
var scrollScore = calculateScrollScore();
var pageViewScore = calculatePageViewScore();
var interactionScore = calculateInteractionScore();
var contentScore = calculateContentEngagementScore();
// Apply weights
var weightedScore = (
(timeScore * config.weights.timeOnPage) +
(scrollScore * config.weights.scrollDepth) +
(pageViewScore * config.weights.pageViews) +
(interactionScore * config.weights.interactions) +
(contentScore * config.weights.contentEngagement)
) / 100;
// Bonus for high-intent pages
var currentPath = window.location.pathname.toLowerCase();
var isHighIntentPage = config.highIntentPages.some(function(page) {
return currentPath.includes(page);
});
if (isHighIntentPage) {
weightedScore = Math.min(weightedScore + 15, 100);
}
return Math.round(weightedScore);
}
function getIntentLevel(score) {
if (score >= config.thresholds.high) return 'high';
if (score >= config.thresholds.medium) return 'medium';
return 'low';
}
function getScrollPercentage() {
var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
var scrollHeight = document.documentElement.scrollHeight - window.innerHeight;
return scrollHeight > 0 ? Math.round((scrollTop / scrollHeight) * 100) : 0;
}
function trackInteraction(eventType, isHighValue) {
sessionData.interactions++;
if (isHighValue) {
sessionData.highValueInteractions++;
}
debugLog('Interaction tracked:', {
type: eventType,
isHighValue: isHighValue,
total: sessionData.interactions
});
}
function updateContentEngagementTime() {
// Simple engagement detection based on focus/visibility
if (document.visibilityState === 'visible' && document.hasFocus()) {
sessionData.contentEngagementTime += config.scoringInterval / 1000;
}
}
function scoreSession() {
updateContentEngagementTime();
var newScore = calculateOverallScore();
var newIntentLevel = getIntentLevel(newScore);
sessionData.lastScore = sessionData.currentScore;
sessionData.currentScore = newScore;
sessionData.intentLevel = newIntentLevel;
var eventData = {
event: config.events.intentScored,
intent_score: newScore,
intent_level: newIntentLevel,
session_time_on_page: sessionData.totalTimeOnPage,
session_scroll_depth: sessionData.maxScrollDepth,
session_page_views: sessionData.pageViews,
session_interactions: sessionData.interactions,
session_high_value_interactions: sessionData.highValueInteractions,
session_engagement_ratio: Math.round((sessionData.contentEngagementTime / sessionData.totalTimeOnPage) * 100),
score_change: newScore - sessionData.lastScore
};
window.dataLayer = window.dataLayer || [];
window.dataLayer.push(eventData);
// Fire high intent event if threshold crossed
if (newIntentLevel === 'high' && sessionData.lastScore < config.thresholds.high) {
window.dataLayer.push({
event: config.events.highIntent,
intent_score: newScore,
session_data: sessionData
});
debugLog('High intent detected!', { score: newScore, data: sessionData });
}
// Fire score update event if significant change
if (Math.abs(newScore - sessionData.lastScore) >= 10) {
window.dataLayer.push({
event: config.events.intentUpdated,
intent_score_previous: sessionData.lastScore,
intent_score_current: newScore,
intent_level: newIntentLevel
});
}
debugLog('Session scored:', {
score: newScore,
level: newIntentLevel,
change: newScore - sessionData.lastScore,
data: sessionData
});
}
function initScrollTracking() {
window.addEventListener('scroll', function() {
var scrollPercent = getScrollPercentage();
sessionData.maxScrollDepth = Math.max(sessionData.maxScrollDepth, scrollPercent);
});
}
function initInteractionTracking() {
// Track clicks
document.addEventListener('click', function(e) {
var isHighValue = false;
var element = e.target;
// Check for high-value elements
if (element.matches('a[href*="pricing"], a[href*="demo"], a[href*="trial"], button[type="submit"]')) {
isHighValue = true;
}
trackInteraction('click', isHighValue);
});
// Track form interactions
document.addEventListener('focus', function(e) {
if (e.target.matches('input, textarea, select')) {
trackInteraction('form_focus', true);
}
}, true);
// Track video plays
document.addEventListener('play', function(e) {
if (e.target.tagName === 'VIDEO') {
trackInteraction('video_play', true);
}
}, true);
}
function initDataLayerListener() {
// Listen for high-value events from other scripts
if (window.dataLayer) {
var originalPush = window.dataLayer.push;
window.dataLayer.push = function() {
var args = Array.prototype.slice.call(arguments);
args.forEach(function(data) {
if (data.event && config.highValueInteractions.includes(data.event)) {
trackInteraction(data.event, true);
}
});
return originalPush.apply(this, arguments);
};
}
}
function startScoring() {
scoringTimer = setInterval(scoreSession, config.scoringInterval);
debugLog('Intent scoring started with ' + config.scoringInterval + 'ms interval');
}
function stopScoring() {
if (scoringTimer) {
clearInterval(scoringTimer);
scoringTimer = null;
}
}
function handlePageVisibility() {
document.addEventListener('visibilitychange', function() {
if (document.visibilityState === 'hidden') {
stopScoring();
} else {
startScoring();
}
});
}
function init() {
debugLog('Initializing Session Intent Scorer');
initScrollTracking();
initInteractionTracking();
initDataLayerListener();
handlePageVisibility();
startScoring();
// Initial score
setTimeout(scoreSession, 1000);
}
// Initialize when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
// Handle page navigation (for SPAs)
window.addEventListener('beforeunload', function() {
stopScoring();
// Final score before leaving
scoreSession();
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'session_intent_final',
final_intent_score: sessionData.currentScore,
final_intent_level: sessionData.intentLevel,
session_duration: sessionData.totalTimeOnPage
});
});
// Expose utility functions
window.sessionIntentScorer = {
getCurrentScore: function() {
return sessionData.currentScore;
},
getSessionData: function() {
return sessionData;
},
forceScore: function() {
scoreSession();
},
addHighValueInteraction: function(eventType) {
trackInteraction(eventType, true);
}
};
})();
</script>
💡 Pro Tip: Copy the entire code block above and paste it directly into a GTM Custom HTML tag. The script is self-contained and ready to use immediately.