Отправка заявок с сайта в Telegram с помощью Яндекс Тег Менеджера
Сегодня вы познакомитесь с нестандартными возможностями Яндекс Тег Менеджера и узнаете, как решить нетривиальную задачу - отправлять заявки с сайта в Telegram своими руками.
Яндекс Тег Менеджер открывает практически безграничные возможности. С его помощью эффективно решаются самые разные задачи маркетологов, аналитиков и разработчиков. При этом парадокс инструмента в том, что чем глубже его изучаешь, тем яснее понимаешь, как много еще предстоит узнать. Одна из таких нестандартных задач, доступных для реализации - это отправка заявок с сайта напрямую в мессенджер Telegram.
Чтобы проще было понять, о чем идет речь, я записал короткое видео демонстрации того, что мы будем учиться отслеживать:
Пользователь заходит к вам на сайт, оставляет заявку, и вы сразу получаете ее в Telegram. Реализовать это можно самостоятельно, без каких-либо финансовых затрат, используя только возможности Telegram и Яндекс Тег Менеджера.
Какой практический смысл этой настройки?
- продемонстрировать нестандартные возможности работы с Яндекс Тег Менеджером;
- иметь запасной вариант приема обращений (дополнение к CRM-системе, e-mail и т.д.);
- потому что это бесплатно и просто, а значит каждый может попробовать настроить;
- забавы ради.
Как настроить отправку заявок с сайта в Telegram с помощью Яндекс Тег Менеджера? Последовательность сводится к нескольким простым шагам:
- создание Telegram-бота;
- получение токена;
- активация бота;
- получение chat id;
- настройка извлечения данных из полей формы в Яндекс Тег Менеджере;
- отправка заявок с сайта в Telegram;
- проверка настроек (отладка).
Давайте рассмотрим каждый шаг подробнее.
Создание Telegram-бота
Рекомендация: для удобства работы и тестирования установите десктопную версию Telegram.
Чтобы создать бота в Telegram, в поиске вам необходимо найти самого главного - @botfather (с галочкой):
Нажмите на кнопку Start или введите /start:
Вы увидите список команд для создания бота или управлениями текущими (уже созданными):
В списке есть команда /newbot. Данная функция позволяет создать нового бота. Вы можете прописать эту команду вручную в поле отправки сообщения или просто нажать на эту команду в списке:
Придумайте имя для бота и нажмите Enter (например - telegramleads):
На следующем шаге выберите логин (username) для вашего бота. Он должен заканчиваться на bot. Например: TetrisBot или tetris_bot (в моем примере - tg_lbot):
Если логин занят, вам придет уведомление: Sorry, this username is already taken. Please try something different. Вам нужно будет придумать другой username для своего бота.
Сохраните токен, который бот пришлет в ответном сообщении. Он понадобится вам в дальнейшем:
Затем следует активировать бота. Чтобы это сделать, вам нужно найти его в поиске Telegram и нажать на Start:
Дополнительно можете в чат отправить какой-нибудь текст. Так вы точно активируйте работу Telegram-бота.
Теперь необходимо получить chat id. Вставьте в браузер ссылку:
|
1 |
https://api.telegram.org/botXXXXXXXXXXXXXXXXXXXXXXX/getUpdates |
, где XXXXXXXXXXXXXXXXXX – ваш токен.
Результат в браузере должен быть примерно такой:
Сохраните chat id (в моем примере - 49472219). Он понадобится вам в дальнейшем. На этом настройка Telegram-бота завершена.
Активация пользовательского HTML-тега
Первым делом вам необходимо активировать опцию Пользовательский HTML в настройках счетчика Яндекс Метрики. Для этого перейдите в раздел Настройки - Счетчик:
И включите функцию Пользовательский HTML:
Пользовательский HTML в Yandex Tag Manager (YTM) - это тип тега, который позволяет добавлять на сайт произвольный HTML-код, JavaScript или другие скрипты, которые не поддерживаются стандартными тегами и которых нет в каталоге шаблонов. Код будет выполняться при срабатывании триггера, в нем также можно использовать переменные для динамической подстановки нужных значений.
Сохраните изменения.
Настройка извлечения данных из полей формы
Поскольку в Яндекс Тег Менеджере на момент написания этого руководства нет пользовательской переменной Собственный код JavaScript (в отличие от Google Tag Manager, где такая переменная есть), то и извлечь значения из полей формы таким способом мы не можем. В шаблонах переменных тоже пока нет соответствующего метода API. Но есть иное решение. Оно основано на том, что мы используем специальный JavaScript-код в теге типа Пользовательский HTML, который отслеживает заполнение значения в поле формы (по CSS-селектору) и отправляет событие в dataLayer.
Пример скрипта для отслеживания одного поля формы:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<script> (function() { // Находим поле формы по CSS-селектору var field = document.querySelector('CSS-селектор'); // Проверяем наличие поля и его значения if (field && field.value) { // Инициализируем dataLayer если не существует window.dataLayer = window.dataLayer || []; // Отправляем событие dataLayer.push({ 'event': 'send_form', 'field_phone': field.value }); } })(); </script> |
, где вместо CSS-селектор вы задаете CSS-селектор вашего HTML-поля формы.
Чтобы лучше разобраться в CSS-селекторах, посмотрите мою лекцию на YouTube:
Или на Rutube:
А также прочитайте несколько материалов, связанных с селекторами, поскольку без фундаментальных основ работы вам будет сложно выполнять все последующие сценарии для своего проекта:
- CSS-селекторы в Google Tag Manager. Часть I
- Селекторы в jQuery. Часть II
- Регулярные выражения в CSS-селекторах и GTM
- CSS Selector Tester и его аналоги
- Google Tag Manager и jQuery
Примечание: материалы и видеоурок посвящены диспетчеру тегов Google, но информация также актуальна и для Яндекс Тег Менеджера.
Пример скрипта для отслеживания нескольких полей формы:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<script> (function() { // Находим форму по селектору (замените на ваш) var form = document.querySelector('СSS-селектор'); // Если форма не найдена — выходим if (!form) return; // Объект для хранения данных формы var formData = {}; // Находим все поля с атрибутом name var inputs = form.querySelectorAll('input[name], textarea[name], select[name]'); // Собираем заполненные поля inputs.forEach(function(field) { if (field.value && field.value.trim()) { formData[field.name] = field.value.trim(); } }); // Отправляем в dataLayer только если есть данные if (Object.keys(formData).length > 0) { window.dataLayer = window.dataLayer || []; dataLayer.push({ 'event': 'formSubmissionData', 'formData': formData }); } })(); </script> |
, где вместо СSS-селектор вам необходимо вставить CSS-селектор не конкретного поля формы, а самой формы.
Поскольку мы хотим передать в Google Таблицу значения всех полей формы, то воспользуемся вторым вариантом - скриптом для отслеживания нескольких полей формы.
Как определить CSS-селектор формы? В браузере откройте консоль разработчика (клавиша F12 для Google Chrome и Mozilla Firefox). Найдите в структуре DOM-дерева тег <form> (в HTML формы размечаются именно этим тегом). Выделив его, нажмите правой кнопкой мыши и выберите пункт Copy - Copy selector (Копировать - Копировать селектор):
Скопируйте это значение к себе в блокнот. Вернитесь в Яндекс Тег Менеджер, откройте раздел Теги и создайте тег типа Пользовательский HTML. Вставьте в него нижеприведенный код:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
<script> (function() { // ========== ПОЛЬЗОВАТЕЛЬСКИЕ НАСТРОЙКИ ========== // Укажите CSS-селектор вашей формы (обязательно!) var FORM_SELECTOR = 'selector'; // Примеры: '#contactForm', '.main-form', 'form.ajax' // ================================================= // Находим форму по селектору var form = document.querySelector(FORM_SELECTOR); // Если форма не найдена — выходим без ошибки if (!form) return; // ========== ФУНКЦИИ СБОРА ДАННЫХ ========== // Получение имени поля из разных источников (без привязки к name) function getFieldName(field) { // 1. Атрибут name if (field.name) return field.name; // 2. Атрибут id if (field.id) return field.id; // 3. Атрибут data-name if (field.dataset && field.dataset.name) return field.dataset.name; // 4. Текст из связанного label (через for="id") if (field.id) { var label = document.querySelector('label[for="' + field.id + '"]'); if (label) { var labelText = label.innerText.trim().replace(/\*$/, '').replace(/:/g, '').trim(); if (labelText) return labelText; } } // 5. Ближайший label (для полей без id) var parentLabel = field.closest('label'); if (parentLabel) { var labelText = parentLabel.innerText.trim().replace(/\*$/, '').replace(/:/g, '').trim(); if (labelText) return labelText; } // 6. Placeholder (очищенный от спецсимволов) if (field.placeholder) { var placeholder = field.placeholder.trim().substring(0, 30); if (placeholder) return 'field_' + placeholder.replace(/[^a-zа-яё0-9]/gi, '_'); } // 7. Тип + индекс (fallback на случай, если ничего не подошло) var index = Array.from(form.querySelectorAll(field.tagName)).indexOf(field); return field.type + '_' + index; } // Получение значения поля (универсальная) function getFieldValue(field) { // Чекбоксы и радио-кнопки if (field.type === 'checkbox' || field.type === 'radio') { if (field.checked) { return field.value || (field.type === 'checkbox' ? 'checked' : 'on'); } return null; } // Выпадающие списки (включая multiple) if (field.tagName === 'SELECT') { if (field.multiple) { var selected = []; for (var i = 0; i < field.options.length; i++) { if (field.options[i].selected) { selected.push(field.options[i].value || field.options[i].text); } } return selected.length ? selected : null; } else { return field.options[field.selectedIndex] ? (field.value || field.options[field.selectedIndex].text) : null; } } // Обычные текстовые поля var val = field.value !== undefined && field.value !== null ? String(field.value).trim() : ''; return val !== '' ? val : null; } // Сбор всех данных формы function getFormData(formElement) { var formData = {}; // Собираем все поля ввода var fields = formElement.querySelectorAll('input, textarea, select'); fields.forEach(function(field) { // Пропускаем кнопки if (field.type === 'submit' || field.type === 'button' || field.type === 'reset') return; // Пропускаем скрытые технические поля (например, CSRF-токены) if (field.type === 'hidden' && (!field.name || field.name.indexOf('csrf') > -1)) return; var fieldName = getFieldName(field); var value = getFieldValue(field); if (value !== null && value !== undefined && value !== '') { // Обработка нескольких полей с одинаковым именем (например, группа чекбоксов) if (formData[fieldName]) { if (!Array.isArray(formData[fieldName])) { formData[fieldName] = [formData[fieldName]]; } formData[fieldName].push(value); } else { formData[fieldName] = value; } } }); return formData; } // Отправка данных в dataLayer function sendToDataLayer(formElement, formData, isValid) { // Если нет данных — ничего не отправляем if (Object.keys(formData).length === 0) return; window.dataLayer = window.dataLayer || []; var payload = { 'event': 'form_submission_data', // Основное событие 'form_selector': FORM_SELECTOR, // Селектор формы 'form_id': formElement.id || '', // ID формы (если есть) 'form_class': formElement.className || '', // Класс формы (если есть) 'form_action': formElement.action || '', // Адрес отправки 'form_method': formElement.method || 'get', // Метод отправки 'form_valid': isValid !== undefined ? isValid : true, // Прошла ли валидацию 'formData': formData // Собранные данные }; // Удаляем пустые поля для чистоты объекта for (var key in payload) { if (payload.hasOwnProperty(key) && payload[key] === '') { delete payload[key]; } } dataLayer.push(payload); } // Проверка валидности формы (HTML5 + required) function isFormValid(formElement) { // Стандартная HTML5-валидация if (!formElement.checkValidity()) return false; // Дополнительная проверка обязательных полей var requiredFields = formElement.querySelectorAll('[required]'); for (var i = 0; i < requiredFields.length; i++) { var field = requiredFields[i]; var val = getFieldValue(field); if (!val || val === '') { return false; } } return true; } // ========== НАВЕШИВАНИЕ ОБРАБОТЧИКА СОБЫТИЙ ========== var isSubmitting = false; // Флаг для защиты от повторной отправки form.addEventListener('submit', function(e) { // Защита от дублей if (isSubmitting) return; var isValid = isFormValid(form); var formData = getFormData(form); // Отправляем данные в dataLayer sendToDataLayer(form, formData, isValid); // Если форма не прошла валидацию — отменяем стандартную отправку if (!isValid) { e.preventDefault(); // Отправляем отдельное событие о неудачной валидации window.dataLayer = window.dataLayer || []; dataLayer.push({ 'event': 'form_validation_failed', 'form_selector': FORM_SELECTOR, 'form_id': form.id || '' }); return; } // Устанавливаем блокировку на 3 секунды (защита от двойного клика) isSubmitting = true; setTimeout(function() { isSubmitting = false; }, 3000); }); })(); </script> |
В строке:
|
1 |
var FORM_SELECTOR = 'selector'; |
Вместо selector вставьте значение селектора своей формы, которое вы скопировали на предыдущем шаге:
Больше никаких изменений в коде не требуется. Вы можете проверить код на ошибки, нажав на кнопку Проверить код под редактором HTML. Их быть не должно.
В качестве триггера активации укажите Просмотр страницы. Задайте тегу название (например - HTML - Отправка формы с полями) и сохраните его.
Представленный выше код - это универсальный скрипт для автоматического сбора данных с любых веб-форм и отправки их с использованием уровня данных (dataLayer). Он не требует наличия атрибута name у полей, так как автоматически определяет их имена по id, тексту связанной метки (label) или placeholder. Скрипт самостоятельно находит форму по указанному вами CSS-селектору, корректно обрабатывает все типы полей (текст, чекбоксы, радио-кнопки, выпадающие списки), проверяет валидность формы, защищает от повторной отправки и в случае успеха (или ошибки валидации) отправляет в dataLayer структурированные данные о заполненных полях, включая мета-информацию о форме (ID, класс, метод отправки).
Теперь перейдите в раздел Триггеры и создайте триггер типа Специальное событие. Задайте ему следующие настройки:
- Название события - form_submission_data|form_validation_failed (именно так, как здесь!)
- Поставьте галочку Использовать регулярные выражения
Задайте триггеру название (например - Отправка формы с полями) и сохраните его.
Теперь вы можете воспользоваться режимом предварительного просмотра, чтобы проверить выполнение кода и корректное извлечения значений из полей формы. Для этого запустите режим отладки Яндекс Тег Менеджера и отправьте тестовую заявку на своем сайте. Если вы все сделали правильно, то на шкале событий должно появиться событие form_submission_data:
Нажав на него, перейдите на вкладку DataLayer. Там вы должны увидеть данные по всей формы, включая значения заполненных полей:
Если это так, ты вы все сделали правильно. Если код не сработал, попробуйте доработать его под свой проект с помощью больших языковых моделей (ChatGPT, Gemini, DeepSeek, Qwen и др.).
После того как вы убедились в корректности получения данных полей формы, необходимо вернуться в Яндекс Тег Менеджер и создать пользовательские переменные типа Переменная уровня данных. С использованием точечной нотации введите следующие имена переменных:
- formData.name
- formData.email
- formData.message
Так нужно сделать для каждого поля вашей формы, поскольку в Google Таблицах у нас каждый столбец - это отдельное поле формы. В моем примере используется три поля: Имя, Email и Сообщение. У вас может быть другое количество.
Задайте каждой переменной название и сохраните ее (их).
Повторно откройте режим отладки Яндекс Тег Менеджера и еще раз отправьте тестовую заявку. Выберите событие form_submission_data на временной шкале и перейдите на вкладку Переменные. Там напротив каждой созданной переменной вы должны увидеть возвращенное значение:
Поздравляю вас! Мы с вами завершили предварительную подготовку к отправке данных в Telegram.
Итоговый тег отправки заявок в Telegram
Мы с вами:
- создали бота Telegram;
- получили токен и chat id;
- настроили переменные для извлечения полей формы и триггер.
Все, что осталось сделать - создать итоговый тег отправки данных о заявках в Telegram. Для этого перейдите в Яндекс Тег Менеджер и создайте тег типа Пользовательский HTML. Вставьте в него нижеприведенный код:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<script> (function() { // 1. Настройки var botToken = 'ВАШ_ТОКЕН_БОТА'; var chatId = 'ВАШ_CHAT_ID'; // 2. Формат сообщения // Замените "Переменная" на ваши переменные Яндекс Тег Менеджера var text = '<b>🚀 Новая заявка</b>\n\n' + '<b>👤 Имя:</b> ' + '{{ Переменная }}' + '\n' + '<b>📧 Email:</b> ' + '{{ Переменная }}' + '\n' + '<b>💬 Сообщение:</b> ' + '{{ Переменная }}'; // 3. Отправка данных в Telegram var url = 'https://api.telegram.org/bot' + botToken + '/sendMessage'; fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ chat_id: chatId, text: text, parse_mode: 'HTML' }), keepalive: true }); })(); </script> |
Чтобы код заработал, вам нужно внести изменения в трех местах:
- заменить токен бота в переменной botToken = 'ВАШ_ТОКЕН_БОТА' на реальный ключ, который вы получили от @BotFather при создании бота. Кавычки по бокам должны остаться;
- заменить ID чата в переменной chatId = 'ВАШ_CHAT_ID' на идентификатор группы, куда должны приходить уведомления. Ее вы получили на шаге ранее (см. chat id);
- замените {{ Переменная }} на ваши переменные Яндекс Тег Менеджера, которые извлекают значения из полей формы. Поскольку ваша форма может отличаться от моего примера, как по составу полей, так и по их количеству, вам потребуется скорректировать формат сообщения под себя.
Таким образом, этот код представляет собой легковесный скрипт для автоматизации уведомлений. Он перехватывает данные из заполненной формы на сайте через Яндекс Тег Менеджер и мгновенно отправляет их в бота Telegram. Скрипт собирает значения заданных переменных (имя, телефон, e-mail и другие поля, которые вы добавите), формирует из них структурированное HTML-сообщение и передает его в чат с помощью метода fetch. Использование параметра keepalive гарантирует доставку уведомления, даже если пользователь закроет страницу сразу после отправки формы.
В качестве триггера задайте триггер специального события, созданный на предыдущем шаге. Итоговый тег отправки заявок в Telegram в Яндекс Тег Менеджере это будет выглядеть так:
Проверка настроек
Перейдите в режим предварительного просмотра Яндекс Тег Менеджера и повторно отправьте заявку. Если вы все настроили верно, то после ее отправки данные должны прийти в Telegram:
Вот и все! Мы с вами настроили Telegram-бота, который отправляет данные по заявкам только вам. В Telegram вместе с заявкой можно передавать не только сами поля формы, но еще и дополнительную информацию, включая город пользователя, IP-адрес посетителя, источник трафика, utm_метки, Client ID, точную дату обращения и многое другое.
Примечание: о том, как отправлять уведомления в Telegram о 404 ошибках на вашем сайте, читайте в этой статье.
Если у вас в команде несколько человек, и вы хотите, чтобы информация по лидам приходила всем в Telegram, то настройка чуть отличается, а именно:
- после активации бота необходимо создать группу в Telegram;
- вы должны пригласить Telegram-бота в эту группу;
- напишите в группе какое-нибудь сообщение.
Далее настройка аналогична -> переходите к шагу получения chat id (будет другим) через:
|
1 |
https://api.telegram.org/botXXXXXXXXXXXXXXXXXXXXXXX/getUpdates |
И продолжаете по этому руководству.
В завершение не забудьте опубликовать контейнер ЯТМ, чтобы изменения стали доступны для всех пользователей.




















