Интеграция Яндекс Метрики и Телеграм: как отслеживать статистику взаимодействия с ботом
Телеграм сейчас не только один из самых популярных мессенджеров, но и важный канал коммуникации с клиентами. Часто Телеграм-бот становится промежуточным шагом на пути пользователя к покупке или основной точкой совершения конверсии. Поэтому важно анализировать, как пользователи взаимодействуют с чат-ботом, чтобы своевременно выявлять и устранять проблемы в их опыте общения.
Собрать полную информацию о пользователе помогает Яндекс Метрика. Она позволяет узнать:
откуда пришел на сайт;
откуда перешел в чат-бот;
как именно взаимодействовал с чат-ботом и т. д.
В этой статье мы разберем:
как передавать историю взаимодействия с чат-ботом в Яндекс Метрику;
как определить, кто именно перешел к вашему чат-боту в Телеграме;
как подготовить скрипт для чат-бота в Телеграме.
Как передавать историю взаимодействия с чат-ботом в Яндекс Метрику
Код счетчика Яндекс Метрики невозможно напрямую встроить в чат-бот. Однако для отслеживания действий пользователей можно воспользоваться 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 сразу после отправки хита просмотра страницы.
Таким образом, используя совместно сайт, чат-бот и Яндекс Метрику, можно собрать единую картину поведения пользователя. Специалисты по маркетингу и аналитике получат возможность проследить весь путь клиента: от первого визита на сайт до финальных действий в чат-боте. Эти данные помогут качественнее улучшить пользовательский опыт и повысить эффективность рекламных кампаний