Home
Live Session Intent Scorer
🎯

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.

Lead ScoringAdvancedLead Scoring & Analytics

Key Features

Real-time behavioral scoring
Scroll depth analysis
Click pattern recognition
Time-based engagement metrics
Custom scoring algorithms
Lead qualification automation

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.