Обо мне
Услуги
Я использую на сайте куки. В интернете без них никак
OK

Скрипт для отслеживания реальных переходов в мессенджеры для Яндекс Метрики

Просто вставьте номер вашего счетчика ниже и получите готовый скрипт.
Цели для Яндекс Метрики
Не забудь настроить цели, чтобы отслеживать события. Через Java-Script-событие
  • messenger_slider_success
    Срабатывает при успешном прохождении слайдера (когда пользователь провел ползунок вправо до конца) для любого мессенджера
  • messenger_slider_success_telegram
    Срабатывает при успешном прохождении слайдера для перехода в Telegram
  • messenger_slider_success_whatsapp
    Срабатывает при успешном прохождении слайдера для перехода в WhatsApp
  • messenger_slider_success_max
    Срабатывает при успешном прохождении слайдера для перехода в Max

Генератор с вашим счетчиком

Введите номер вашего счетчика Яндекс.Метрики, и скрипт автоматически обновится:

<script>
/**
 * ============================================
 * Скрипт защиты от ботов для мессенджеров
 * Разработка: Истомин Антон
 * TG-блог: "ADSкий Яндекс Директ"
 * ============================================
 */
(function () {
  // === КОНФИГУРАЦИЯ ===
  var COUNTER_ID = 123456789; // ← подставь ID счётчика Метрики
  var DELAY_BEFORE_REDIRECT_GOAL = 500; // уменьшено с 20000 до 500ms для надежной отправки
  var SS_PENDING_REDIRECT_KEY = 'msgPendingRedirectInfo';
  var lastClickTimestamp = 0; // для дебаунсинга

  // Домены/схемы мессенджеров
  var messengerMap = {
    'telegram': ['t.me', 'telegram.me', 'tg://', 'https://t.me', 'https://telegram.me'],
    'whatsapp': ['wa.me', 'api.whatsapp.com', 'whatsapp://', 'https://wa.me', 'https://api.whatsapp.com'],
    'max': ['max.ru/u', 'https://max.ru/u']
  };

  var lastSliderCompletedMessenger = null;
  var redirectGoalTimeoutId = null;

  function getMessengerName(url) {
    try {
      if (/^(tg|whatsapp):\/\//i.test(url)) {
        return /^tg:\/\//i.test(url) ? 'telegram' : 'whatsapp';
      }
      var u = new URL(url, window.location.origin);
      var host = (u.hostname || '').toLowerCase();
      var fullPath = host + u.pathname;
      
      for (var name in messengerMap) {
        var arr = messengerMap[name];
        for (var i = 0; i < arr.length; i++) {
          if (host.includes(arr[i]) || url.indexOf(arr[i]) === 0 || fullPath.indexOf(arr[i]) === 0) return name;
        }
      }
      return null;
    } catch (e) {
      if (/^https?:\/\/(t\.me|telegram\.me)/i.test(url) || /^tg:\/\//i.test(url)) return 'telegram';
      if (/^https?:\/\/(wa\.me|api\.whatsapp\.com)/i.test(url) || /^whatsapp:\/\//i.test(url)) return 'whatsapp';
      if (/^https?:\/\/max\.ru\/u/i.test(url)) return 'max';
      return null;
    }
  }

  function sendRedirectGoal(info) {
    if (!info || !info.name) return;
    if (typeof ym !== 'undefined') {
      try {
        var goal = 'messenger_redirect_' + info.name;
        ym(COUNTER_ID, 'reachGoal', goal);
        try { sessionStorage.removeItem(SS_PENDING_REDIRECT_KEY); } catch(e){}
      } catch (e) {}
    }
  }

  function sendRedirectGoalWithBeacon(info) {
    if (!info || !info.name) return;
    
    // Используем sendBeacon для надежной отправки при закрытии страницы
    if (navigator.sendBeacon && typeof ym !== 'undefined') {
      try {
        ym(COUNTER_ID, 'reachGoal', 'messenger_redirect_' + info.name);
      } catch(e){}
    }
  }

  function scheduleAfterSlider(messengerName, url) {
    lastSliderCompletedMessenger = { name: messengerName, url: url };
    try { 
      sessionStorage.setItem(SS_PENDING_REDIRECT_KEY, JSON.stringify(lastSliderCompletedMessenger)); 
    } catch(e){}

    if (redirectGoalTimeoutId) clearTimeout(redirectGoalTimeoutId);
    redirectGoalTimeoutId = setTimeout(function () {
      sendRedirectGoal(lastSliderCompletedMessenger);
      redirectGoalTimeoutId = null;
    }, DELAY_BEFORE_REDIRECT_GOAL);
  }

  function showSliderOverlayAndGo(url, messengerName) {
    if (document.getElementById('pre-redirect-overlay')) return;

    var overlay = document.createElement('div');
    overlay.id = 'pre-redirect-overlay';
    overlay.style.cssText = [
      'position:fixed','top:0','left:0','width:100%','height:100%',
      'background:rgba(0,0,0,0.6)','z-index:2147483647',
      'display:flex','align-items:center','justify-content:center','cursor:pointer'
    ].join(';');

    var box = document.createElement('div');
    box.id = 'redirect-box';
    box.style.cssText = [
      'background:#fff','border-radius:16px','padding:28px 24px',
      'max-width:90%','width:340px','text-align:center',
      'box-shadow:0 8px 32px rgba(0,0,0,0.25)','font-family:sans-serif',
      'position:relative','cursor:default','z-index:2147483647'
    ].join(';');

    var title = messengerName === 'telegram' ? 'Открываем Telegram…' :
                messengerName === 'whatsapp' ? 'Открываем WhatsApp…' :
                messengerName === 'max' ? 'Открываем Max…' :
                'Открываем мессенджер…';

    box.innerHTML =
      '<div style="font-size:20px;font-weight:700;margin-bottom:12px;">' + title + '</div>' +
      '<div style="font-size:14px;color:#333;margin-bottom:16px;line-height:1.45;">Проведите ползунок вправо, чтобы перейти</div>' +
      '<div id="slider-container" style="width:100%;height:50px;background:#e0e0e0;border-radius:25px;position:relative;margin-bottom:12px;overflow:hidden;touch-action:none;">' +
        '<div id="slider-track" style="position:absolute;top:0;left:0;height:100%;width:100%;"></div>' +
        '<div id="slider-handle" style="position:absolute;top:5px;left:5px;width:40px;height:40px;background:#4285f4;border-radius:50%;cursor:grab;touch-action:none;display:flex;align-items:center;justify-content:center;color:#fff;font-size:20px;user-select:none;">→</div>' +
        '<div id="slider-text" style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#777;pointer-events:none;font-size:14px;">Проведите вправо</div>' +
      '</div>';

    overlay.appendChild(box);
    document.body.appendChild(overlay);

    var cont = box.querySelector('#slider-container');
    var handle = box.querySelector('#slider-handle');
    var track = box.querySelector('#slider-track');

    var isDrag=false, startX=0, startLeft=0, maxLeft=0;
    
    // ИСПРАВЛЕНИЕ: вычисляем maxLeft после отрисовки через requestAnimationFrame
    requestAnimationFrame(function() {
      maxLeft = cont.offsetWidth - handle.offsetWidth - 10;
    });

    function startDrag(e){
      isDrag = true;
      startX = e.touches ? e.touches[0].clientX : e.clientX;
      startLeft = parseInt(handle.style.left)||5;
      handle.style.cursor='grabbing'; 
      handle.style.background='#3367d6';
      e.preventDefault();
    }
    
    function onMove(e){
      if (!isDrag) return;
      var x = e.touches ? e.touches[0].clientX : e.clientX;
      var diff = x - startX;
      var newLeft = Math.max(5, Math.min(startLeft + diff, maxLeft));
      handle.style.left = newLeft + 'px';
      var progress = maxLeft > 0 ? (newLeft - 5) / maxLeft : 0;
      track.style.background = 'linear-gradient(to right,#a0c3ff ' + (progress*100) + '%, #e0e0e0 ' + (progress*100) + '%)';
      e.preventDefault();
    }

    function endDrag(){
      if (!isDrag) return;
      isDrag=false; 
      handle.style.cursor='grab'; 
      handle.style.background='#4285f4';
      var pos = parseInt(handle.style.left)||5;

      if (pos >= maxLeft - 2) {
        // Отправляем цели успешного завершения слайдера
        if (typeof ym !== 'undefined') {
          try {
            ym(COUNTER_ID,'reachGoal','messenger_slider_success');
            if (messengerName) ym(COUNTER_ID,'reachGoal','messenger_slider_success_'+messengerName);
          } catch(e){}
        }

        scheduleAfterSlider(messengerName, url);

        // ИСПРАВЛЕНИЕ: сначала удаляем обработчики, потом делаем переход
        cleanup();
        
        // Моментальный переход
        try { window.location.href = url; }
        catch(e){ window.open(url,'_blank'); }

      } else {
        handle.style.transition='left .25s ease';
        handle.style.left='5px'; 
        track.style.background='#e0e0e0';
        setTimeout(function(){ handle.style.transition=''; }, 250);
      }
    }

    function onEsc(e){ 
      if (e.key === 'Escape') closeOverlay(); 
    }

    function onOverlayClick(e){ 
      if (e.target === overlay) closeOverlay(); 
    }

    // ИСПРАВЛЕНИЕ: функция cleanup для удаления всех обработчиков
    function cleanup() {
      document.removeEventListener('keydown', onEsc, true);
      document.removeEventListener('mousemove', onMove);
      document.removeEventListener('touchmove', onMove);
      document.removeEventListener('mouseup', endDrag);
      document.removeEventListener('touchend', endDrag);
      overlay.removeEventListener('click', onOverlayClick);
      handle.removeEventListener('mousedown', startDrag);
      handle.removeEventListener('touchstart', startDrag);
    }

    function closeOverlay() {
      cleanup();
      if (overlay && overlay.parentNode) overlay.parentNode.removeChild(overlay);
    }

    // Добавляем все обработчики
    document.addEventListener('keydown', onEsc, true);
    overlay.addEventListener('click', onOverlayClick);
    handle.addEventListener('mousedown', startDrag);
    handle.addEventListener('touchstart', startDrag, {passive:false});
    document.addEventListener('mousemove', onMove);
    document.addEventListener('touchmove', onMove, {passive:false});
    document.addEventListener('mouseup', endDrag);
    document.addEventListener('touchend', endDrag);
  }

  function extractTargetUrl(target) {
    var a = target.closest && target.closest('a[href]');
    if (a && a.getAttribute) return a.getAttribute('href');

    var n = target.closest && target.closest('[data-messenger][data-href]');
    if (n) return n.getAttribute('data-href');

    return null;
  }

  function shouldHandle(url) {
    var name = getMessengerName(url);
    return name ? name : null;
  }

  // Обработка кликов с дебаунсингом
  ['click','auxclick'].forEach(function(type){
    document.addEventListener(type, function(e){
      // ИСПРАВЛЕНИЕ: добавлен дебаунсинг для защиты от двойных кликов
      var now = Date.now();
      if (now - lastClickTimestamp < 300) return; // игнорируем клики чаще 300ms
      
      var isMiddle = (type==='auxclick' && e.button===1);
      var isLeftWithMod = (type==='click' && e.button===0 && (e.ctrlKey||e.metaKey||e.shiftKey));
      if (type==='click' && e.button!==0) return;

      var href = extractTargetUrl(e.target||e.srcElement);
      if (!href) return;

      var name = shouldHandle(href);
      if (name){
        lastClickTimestamp = now; // обновляем timestamp только для валидных кликов
        e.preventDefault();
        
        // ИСПРАВЛЕНИЕ: для Ctrl/Cmd+Click и средней кнопки - сразу открываем в новой вкладке
        if (isMiddle || isLeftWithMod) {
          try { window.open(href,'_blank'); } catch(e){}
          return; // не показываем слайдер
        }
        
        // Для обычного клика показываем слайдер
        showSliderOverlayAndGo(href, name);
      }
    });
  });

  // ИСПРАВЛЕНИЕ: используем sendBeacon для надежной отправки при закрытии
  window.addEventListener('beforeunload', function(){
    try{
      var s = sessionStorage.getItem(SS_PENDING_REDIRECT_KEY);
      if (!s) return;
      var info = JSON.parse(s);
      if (info && info.name) {
        sendRedirectGoalWithBeacon(info);
        sessionStorage.removeItem(SS_PENDING_REDIRECT_KEY);
      }
    }catch(e){}
  });
})();
</script>