Интеграция Яндекс Метрики и Телеграм: как отслеживать статистику взаимодействия с ботом
Собрать полную информацию о пользователе помогает Яндекс Метрика. Она позволяет узнать:
-
откуда пришел на сайт;
-
откуда перешел в чат-бот;
-
как именно взаимодействовал с чат-ботом и т. д.
В этой статье мы разберем:
-
как передавать историю взаимодействия с чат-ботом в Яндекс Метрику;
-
как определить, кто именно перешел к вашему чат-боту в Телеграме;
-
как подготовить скрипт для чат-бота в Телеграме.
Как передавать историю взаимодействия с чат-ботом в Яндекс Метрику
Код счетчика Яндекс Метрики невозможно напрямую встроить в чат-бот. Однако для отслеживания действий пользователей можно воспользоваться Measurement Protocol — как это сделать, читайте в нашей статье.
Прежде чем приступать к внедрению Measurement Protocol, необходимо определить, какие действия пользователей чат-бота нужно отслеживать. Для этого стоит представить чат-бот как условный сайт и продумать, каким образом передавать хиты о взаимодействиях пользователя на этом «сайте».
Отслеживать можно следующие типы хитов:
-
просмотры страниц (экраны),
-
события,
-
цели,
-
E-commerce.
Разберем подробнее каждый тип хитов.
Просмотры страниц (обязательный хит)В Яндекс Метрике для формирования визита (сессии) требуется хотя бы один хит просмотра страницы. Поэтому в чат-боте при переходе пользователя на первый экран следует отправить хит типа pageview. Каждый экран внутри бота можно рассматривать как аналог веб-страницы.
Пример запроса Measurement Protocol для отправки просмотра страницы:
import requests import json import pandas as pd import pandasql as ps #-----------------Для заполнения (начало) ms = '' #Укажите ваш токен tid = 88989734 #Укажите ваш счетчик cid = 1710232430899999999 #Идентификатор ClientID dr = ' https://yandex.ru/' #Реферер dl = ' https://yourdomain.ru/chatbot/main_screen' #URL dt = ' Чат-бот Главный экран' #Заголовок страницы #et = 1728630000 #Время хита (Timestamp, если не передан, будет использовано время получения данных) #-----------------Для заполнения (конец) URL = ' https://mc.yandex.ru/collect/? tid='+str (tid)+'&cid='+str (cid)+'&t=pageview&dr='+str (dr)+'&dl='+str (dl)+'&dt='+str (dt)+'&ms='+str (ms) r_s = requests.get (URL) print (r_s)События (опциональный хит):
Параметры событий могут быть полезны, чтобы детализировать поведение пользователей в чат-боте:
с какими кнопками чаще взаимодействуют;
как отвечают на вопросы бота и т.д.
Событиями можно разметить взаимодействия пользователей с навигацией чат-бота и отправку ими сообщений в чат-боте.
Пример Measurement Protocol для отправки событий:
#Отправка событий import requests import json import pandas as pd import pandasql as ps #-----------------Для заполнения (начало) ms = '' #Укажите ваш токен tid = 88989734 #Укажите ваш cчетчик cid = 1710232430899999999 #Идентификатор ClientID dl = ' https://yourdomain.ru/test1' #URL события params = '{"clickButton»:"Текст кнопки"}' #Параметры события #et = 1728630000 #Время хита (Timestamp, если не передан, будет использовано время получения данных) #-----------------Для заполнения (конец) URL = ' https://mc.yandex.ru/collect/? tid='+str (tid)+'&cid='+str (cid)+'&t=event¶ms='+str (params)+'&dl='+str (dl)+'&ms='+str (ms) r_s = requests.get (URL) print (r_s)Цели (опциональный хит):
Цели в Яндекс Метрике можно настроить на основе определенных просмотров страниц либо срабатывания событий.Пример, как отправить «JavaScript-цель» (цель, срабатывающую по событию) через Measurement Protocol:
import requests import json import pandas as pd import pandasql as ps #-----------------Для заполнения (начало) ms = '' #Укажите ваш токен tid = 88989734 #Укажите ваш счетчик cid = 1710232430899999999 #Идентификатор ClientID dr = ' https://yourdomain.ru/test1' #Реферер ea = ' test_mp' #et = 1728630000 #Время хита (Timestamp, если не передан, будет использовано время получения данных) #-----------------Для заполнения (конец) URL = ' https://mc.yandex.ru/collect/? tid='+str (tid)+'&cid='+str (cid)+'&t=event&dr='+str (dr)+'&ea='+str (ea)+'&ms='+str (ms) r_s = requests.get (URL) print (r_s)E-commerce (опциональный хит):
Если чат-бот используется для продажи товаров, то для удобного анализа можно передавать в Метрику информацию о товарах, с которыми взаимодействует пользователь: сколько и каких товаров было добавлено в корзину; какие товары просматривал пользователь; какие товары были куплены и т. д.
Пример использования Measurement Protocol для передачи данных о покупке (успешное оформление заказа):
import requests import json import pandas as pd import pandasql as ps #-----------------Для заполнения (начало) ms = '' #Укажите ваш токен tid = 88989734 #Укажите ваш счетчик cid = 1710232430899999999 #Идентификатор ClientID pa = ' purchase' #ecom действие с товаром (detail, и т.д.) #et = 1728630000 #Время хита (Timestamp, если не передан, будет использовано время получения данных) #-----------------Для заполнения (конец) #список товаров pr1id = 456 pr1nm = ' iphone' pr1br = ' apple' pr1pr = 50000 pr2id = 459 pr2nm = ' airpods' pr2br = ' apple' pr2pr = '20000' URL = ' https://mc.yandex.ru/collect/? tid='+str (tid)+'&cid='+str (cid)+'&t=event&pa='+str (pa)+'&pr1id='+str (pr1id)+'&pr1nm='+str (pr1nm)+'&pr1br='+str (pr1br)+'&pr1pr='+str (pr1pr)+'&pr2id='+str (pr2id)+'&pr2nm='+str (pr2nm)+'&pr2br='+str (pr2br)+'&pr2pr='+str (pr2pr)+'&ti='+str (ti)+'&tr='+str (tr)+'&ms='+str (ms) r_s = requests.get (URL) print (r_s)Как передать идентификатор пользователя в Телеграм
Если нужно отслеживать действия внутри чат-бота без привязки к сайту, в качестве clientID можно использовать любой уникальный идентификатор. Например, подойдет ID пользователя в самом Телеграме (бот получает его, когда пользователь нажимает кнопку Start).Однако чтобы склеить поведение одного и того же человека на сайте и в Телеграм-боте, необходимо передать в бот clientID, присвоенный ему на сайте. Для этого в ссылку на чат-бота добавляется параметр clientID.Пример ссылки: https://t.me/<название_бота>? start=При переходе по такой ссылке пользователь запускает бота командой /start, передавая параметр clientID. В результате бот получает и этот идентификатор, и данные профиля пользователя из Телеграма.
Пример кода чат-бота в Телеграме:
Для примера разработаем простейший чат-бот для подбора фильмов. Этого будет достаточно, чтобы продемонстрировать отслеживание просмотров экранов и кликов по кнопкам.
import requests import time TOKEN = '' #Укажите токен чат-бота в ТГ. ms = '' #Укажите ваш токен Яндекс Метрики tid = '' #Укажите ваш cчетчик cids = {} #clientID prev = {} #предыдущая страница URL = f' https://api.telegram.org/bot{TOKEN}/' last_update_id = 0 user_states = {} #---------Функции для отправки хитов в Яндекс Метрику (start) #ОТПРАВКА ПРОСМОТРОВ def YM_send_pageView (path, dt, chat_id): cid = cids.get (chat_id, chat_id) #если есть clientID в словаре, то берем его, если нет используем chat_id dl = ' https://yourdomain.ru/chatbot/'+str (path) #URL URL = ' https://mc.yandex.ru/collect/? tid='+str (tid)+'&cid='+str (cid)+'&t=pageview&dl='+str (dl)+'&dt='+str (dt)+'&ms='+str (ms) r_s = requests.get (URL) print (' pageView') print (r_s) #ОТПРАВКА СОБЫТИЙ def YM_send_event_button (path, button, chat_id): cid = cids.get (chat_id, chat_id) #если есть clientID в словаре, то берем его, если нет используем chat_id dl = ' https://yourdomain.ru/chatbot/'+str (path) URL = ' https://mc.yandex.ru/collect/? tid='+str (tid)+'&cid='+str (cid)+'&t=event¶ms={"clickButton»:"'+str (button)+'"}&dl='+str (dl)+'&ms='+str (ms) r_s = requests.get (URL) print (' event') print (r_s) #---------Функции для отправки хитов в Яндекс Метрику (end) # Главное меню main_keyboard = { «keyboard”: [ [{"text”: "🎬 Фильмы"}, {"text”: "📺 Сериалы"}], [{"text”: "🔍 Поиск по жанру"}, {"text”: "✍️ Оставить отзыв"}], [{"text”: "🔥 Топ 10"}, {"text”: "🎲 Случайный"}], [{"text»: "📚 Инструкция"}, {"text»: "🔙 Назад в меню"}], ], «resize_keyboard»: True } def send_message (chat_id, text, reply_markup=None): payload = { «chat_id»: chat_id, «text»: text, «reply_markup»: reply_markup or main_keyboard } requests.post (URL + ' sendMessage', json=payload) def handle_command (message): user_id = message["from"]["id"] chat_id = message["chat"]["id"] text = message.get («text”, "») # Состояния ввода if user_id in user_states: state = user_states[user_id] if state == «waiting_feedback”: send_message (chat_id, f”Спасибо за отзыв!\nТы написал: “{text}”») del user_states[user_id] return elif state == «waiting_genre»: genre = text.lower () recommendations = { «комедия”: ["Очень страшное кино», «Маска», "1+1"], «боевик”: ["Джон Уик», «Терминатор», «Форсаж"], “драма”: ["Зеленая миля», «Престиж», «Остров проклятых"] } films = recommendations.get (genre) if films: send_message (chat_id, f»Рекомендации в жанре '{genre}':\n- " + "\n- ".join (films)) else: send_message (chat_id, «Жанр не найден. Попробуй: комедия, боевик, драма.”) del user_states[user_id] return # Команды if text == "/start»: send_message (chat_id, «Привет! Я бот для рекомендаций фильмов и сериалов. Выбери опцию ниже:”) path = ' start' dt = ' Экран приветствия' YM_send_pageView (path, dt, chat_id) prev[chat_id] = path elif text.startswith ("/start”) and text[len ("/start”):].lstrip () == text[len ("/start»):].lstrip (" "): #доп условия, чтобы обработать clientID send_message (chat_id, «Привет! Я бот для рекомендаций фильмов и сериалов. Выбери опцию ниже:”) client_id = text[len ("/start”):].strip () or None cids[chat_id] = client_id path = ' start' dt = ' Экран приветствия' YM_send_pageView (path, dt, chat_id) prev[chat_id] = path elif text == "🎬 Фильмы»: button = '🎬 Фильмы' YM_send_event_button (prev[chat_id], button, chat_id) send_message (chat_id, «Популярные фильмы:\n- Начало\n- Дюна\n- Матрица”) path = ' movies' dt = ' Фильмы' YM_send_pageView (path, dt, chat_id) prev[chat_id] = path elif text == "📺 Сериалы»: button = '📺 Сериалы' YM_send_event_button (prev[chat_id], button, chat_id) send_message (chat_id, «Популярные сериалы:\n- Шерлок\n- Во все тяжкие\n- Ведьмак”) path = ' series' dt = ' Сериалы' YM_send_pageView (path, dt, chat_id) prev[chat_id] = path elif text == "🔥 Топ 10»: button = '🔥 Топ 10' YM_send_event_button (prev[chat_id], button, chat_id) send_message (chat_id, «Топ 10 IMDb:\n1. Побег из Шоушенка\n2. Крестный отец\n3. Темный рыцарь”) path = ' top10' dt = ' Топ 10' YM_send_pageView (path, dt, chat_id) prev[chat_id] = path elif text == "🎲 Случайный”: button = '🎲 Случайный' YM_send_event_button (prev[chat_id], button, chat_id) import random options = ["Интерстеллар», «Драйв», «Платформа», «Остров проклятых"] send_message (chat_id, f”Советую посмотреть: {random.choice (options)}") path = ' random' dt = ' Случайный' YM_send_pageView (path, dt, chat_id) prev[chat_id] = path elif text == "📚 Инструкция»: button = '📚 Инструкция' YM_send_event_button (prev[chat_id], button, chat_id) send_message (chat_id, «Выбирай кнопки для рекомендаций, отправь отзыв или введи жанр.”) path = ' instructions' dt = ' Инструкция' YM_send_pageView (path, dt, chat_id) prev[chat_id] = path elif text == "🔍 Поиск по жанру»: button = '🔍 Поиск по жанру' YM_send_event_button (prev[chat_id], button, chat_id) send_message (chat_id, «Напиши жанр: комедия, боевик, драма.») user_states[user_id] = «waiting_genre” path = ' search_genre' dt = ' Поиск по жанру' YM_send_pageView (path, dt, chat_id) prev[chat_id] = path elif text == "✍️ Оставить отзыв»: button = '✍️ Оставить отзыв' YM_send_event_button (prev[chat_id], button, chat_id) send_message (chat_id, «Пожалуйста, введи свой отзыв:») user_states[user_id] = «waiting_feedback” path = ' feedback' dt = ' Оставить отзыв' YM_send_pageView (path, dt, chat_id) prev[chat_id] = path elif text == "🔙 Назад в меню»: button = '🔙 Назад в меню' YM_send_event_button (prev[chat_id], button, chat_id) send_message (chat_id, «Возвращаемся в меню.») path = ' menu' dt = ' меню' YM_send_pageView (path, dt, chat_id) prev[chat_id] = path else: send_message (chat_id, «Не понял сообщение. Используй кнопки или напиши отзыв.”) path = '404' dt = '404' YM_send_pageView (path, dt, chat_id) prev[chat_id] = path def poll (): global last_update_id while True: try: res = requests.get (URL + ' getUpdates', params={"offset»: last_update_id + 1, «timeout»: 10}) data = res.json () for update in data["result"]: last_update_id = update["update_id"] if «message» in update: handle_command (update["message"]) except Exception as e: print («Ошибка:», e) time.sleep (3) if __name__ == ' __main__': print («Бот запущен…») poll ()Ключевыми в реализации отправки данных являются две функции:
-
YM_send_pageView — отправка просмотров страниц;
-
YM_send_event_button — отправка событий нажатия кнопки.
В текущем варианте реализации логика отправки хитов рассчитана на то, что пользователь всегда начинает общение с командой /start (первая активация бота). Если же пользователь регулярно возвращается к боту (не начиная заново через /start), следует усложнить логику.
Важно, чтобы при каждом новом сеансе первым отправлялся хит просмотра страницы, а уже затем — хит события (клик по кнопке).
В коде используются два вспомогательных словаря: cids и prev.
cids:
Когда пользователь переходит по ссылке вида https://t.me/your_bot? start=clientID, значение clientID сохраняется в словаре cids. Далее этот идентификатор передается в Яндекс Метрику при отправке хитов.
clientID — идентификатор пользователя в Яндекс Метрике (хранится в cookie _ym_uid при установленном счетчике на сайте). Передача clientID с сайта в бот позволяет связать действия пользователя на сайте и в чат-боте.
Таким образом, вы сможете проследить полный путь пользователя по воронке: от первых касаний рекламных кампаний до финальных шагов внутри чат-бота. Это поможет в дальнейшем оптимизировать ваши рекламные кампании.
prev:
Словарь prev необходим, чтобы в Яндекс Метрике отображалось, какие кнопки нажимал пользователь на том или ином экране.
После нажатия пользователь переходит на новый экран чат-бота. Поэтому URL текущего экрана сохраняется в словаре prev сразу после отправки хита просмотра страницы.
Таким образом, используя совместно сайт, чат-бот и Яндекс Метрику, можно собрать единую картину поведения пользователя. Специалисты по маркетингу и аналитике получат возможность проследить весь путь клиента: от первого визита на сайт до финальных действий в чат-боте. Эти данные помогут качественнее улучшить пользовательский опыт и повысить эффективность рекламных кампаний
Нужна консультация? Напишите нам на почту analyticspace@adventum.ru или оставьте заявку на сайте.
Лучшее в блогах
Вам понравится
На рынке коммуникаций участились случаи появления рейтингов, методология которых не обеспечивает независимость оценки, но позиционируются они как индустриальные. Подобные материалы могут вводить в заблуждение профессиональное сообщество, формируя искаженную картину рынка. Для противодействия такой практике и сохранения доверия отрасли Ассоциация коммуникационных агентств России (АКАР) разработала критерии и принципы формирования индустриальных продуктов.
Ноябрь — пик рекламной активности. Платформа для автоматизации рекламы Telega.in запускает Сезон распродаж, даёт бизнесу скидки до 70% и готовые инструменты для эффективного продвижения в Telegram и MAX. Бренды смогут рассказать о своих акциях, привлечь аудиторию и увеличить продажи.
Неделя рекламы
Энциклопедия обмана