Пользователь не склеился
Почему анонимные и авторизованные события расходятся, один человек выглядит двумя, серверные события не связались с браузерными и после выхода данные идут прежнему пользователю.
На этой странице
- Как устроена склейка
- Решение проблем
- Анонимные и авторизованные события не связались
- Один человек в двух браузерах выглядит двумя
- Идентификатор передан слишком поздно
- Идентификатор менялся
- События с бэкенда не связались с браузерными
- После выхода события продолжают идти на прежнего пользователя
- Что проверить
Склейка личности ломается тихо: отчёты продолжают работать, просто в них двое вместо одного. Эта страница — про то, как отличить настоящую поломку от ожидаемого поведения и что можно исправить, не потеряв историю.
Как устроена склейка
Четыре механизма, и путать их — главный источник ошибочных диагнозов.
| Механизм | Что делает | Когда действует |
|---|---|---|
user_id в самом событии |
задаёт субъект напрямую | сразу, без связок |
| Связка «анонимный → пользователь» | сохраняется вызовом идентификации | сразу после успешного ответа |
| Подстановка на приёме | событию только с anon_id дописывается связанный user_id |
по кэшу связок |
| Перезапись истории | события, собранные до идентификации, привязываются задним числом | фоновой задачей |
Субъект события — это user_id, если он есть, иначе anon_id. Поэтому самый
надёжный способ ничего не склеивать — присылать user_id там, где вы его уже
знаете.
Про перезапись истории важно знать две вещи: задача проверяет новые связки каждые 30 секунд, но сама перезапись занимает время и на один проект выполняется не более одной одновременно. Сразу после первой идентификации отчёты по пользователю могут показывать меньше, чем отчёты по анонимному посетителю, — это нормальный переходный период, а не потеря.
Решение проблем
Анонимные и авторизованные события не связались
Вероятная причина. Вызов идентификации не дошёл до приёма. Из браузера он отправляется один раз и не повторяется: неудача проглатывается без ошибки в консоли. Поэтому обрыв сети, блокировщик или отказ по правам оставляют связку несозданной, а сбор при этом продолжает работать как обычно.
Как проверить. Во вкладке «Сеть» с включённым сохранением журнала войдите в
аккаунт и найдите запрос на /v1/identify. Ожидаемый ответ —
202 с телом {"accepted": 1, "n": 1}. Значимые отказы:
| Ответ | Что означает |
|---|---|
| запроса нет вовсе | вызов идентификации не выполнился |
422 anon_id and user_id are required |
одно из значений пустое |
403 credential_rotation_required |
ключ выпущен до перехода на новую модель прав |
409 privacy_job_active |
в проекте идёт удаление данных, связки временно не пишутся |
Безопасное исправление. Убедитесь, что вызов идентификации выполняется
после того, как разрешён сбор: до согласия он ничего не делает, потому что
анонимного идентификатора ещё не существует. При ответе 403
credential_rotation_required выпустите новый ключ и замените значение — старый
ключ продолжит отправлять события, но операции идентификации ему недоступны.
При 409 повторите позже: в details приходит признак retryable.
Если не помогло. Продублируйте связку с бэкенда. У серверного ключа есть отдельная операция связывания, которая ничего не отправляет в аналитику, а только сохраняет связь, и её результат вы видите в коде ответа. Браузерному токену эта операция недоступна намеренно: иначе любой посетитель мог бы привязать чужой идентификатор к своему устройству. См. идентификацию и раздел Ingest.
Один человек в двух браузерах выглядит двумя
Вероятная причина. Так и должно быть, пока человек не авторизовался.
Анонимный идентификатор живёт в хранилище одного браузера и одного origin. Два
браузера, два устройства, приватное окно, другой поддомен, переход с http на
https — во всех этих случаях анонимные идентификаторы разные, и связать их
между собой нечем: у ActionPulse нет ни межбраузерного отпечатка, ни
кросс-доменных cookie.
Как проверить. Откройте карточку человека и посмотрите блок связанных
идентификаторов: при корректной работе у одного user_id перечислено несколько
анонимных идентификаторов — по одному на браузер. Если карточек две и у каждой
свой user_id, дело не в устройствах, а в самом значении идентификатора — см.
следующие разделы.
Безопасное исправление. Ничего исправлять не нужно: как только человек
авторизовался в каждом браузере и вызвана идентификация, события несут один и
тот же user_id и в отчётах по пользователям он один. Двойным он остаётся
только в той части, что была собрана анонимно и до перезаписи истории.
Если не помогло. Проверьте домены. www.example.com и example.com — разные
origin, а значит и разные анонимные посетители у одного и того же человека в
одном и том же браузере. Один канонический домен для всего трафика — самая
дешёвая профилактика.
Идентификатор передан слишком поздно
Вероятная причина. Идентификация вызывается не там, где человек стал известен, а позже — например, только на странице личного кабинета. Всё, что человек сделал между входом и этой страницей, уходит анонимным.
Как проверить. Пройдите путь входа с открытой вкладкой «Сеть» и посмотрите
порядок запросов: сколько событий на /v1/track ушло до первого запроса на
/v1/identify. Затем посмотрите те же события в списке событий: у них будет
только анонимный идентификатор.
Безопасное исправление. Вызывайте идентификацию в трёх точках: сразу после успешного входа, сразу после успешной регистрации и один раз при загрузке приложения, если сессия уже открыта. Дублирующий вызов не опасен, но каждый создаёт событие идентификации, поэтому не ставьте его в код, который выполняется на каждой странице без условия.
Если не помогло. Помните про порядок: события, отправленные до согласия, не
буферизуются и не досылаются, а перезапись истории привязывает к пользователю
только те события, что были приняты. Если вам важна точная атрибуция первого
касания, посылайте user_id в самом событии, как только он известен, — это
единственный способ, который не зависит ни от связок, ни от фоновой обработки.
Идентификатор менялся
Вероятная причина. У одного анонимного идентификатора может быть только
одна связка, и новая запись её перезаписывает: побеждает последняя. Если на
одном устройстве последовательно вошли два человека без сброса, связка укажет на
второго — и события первого, отправленные позже под тем же анонимным
идентификатором, попадут ко второму. Второй источник — само значение user_id
поменялось на стороне вашего приложения: человек сменил адрес почты, а он
использовался как идентификатор.
Как проверить. В карточке человека посмотрите, не появился ли один и тот же
анонимный идентификатор у двух разных людей в разные периоды. В списке событий
проверьте user_id двух событий, которые вы считаете принадлежащими одному
человеку: значения сравниваются точно, как есть. User-42, user-42 и
" user-42" — три разных человека.
Безопасное исправление. Приведите идентификатор к одной форме на бэкенде до отправки и используйте неизменяемое внутреннее значение — первичный ключ или UUID. Уже собранные события переписать нельзя, поэтому исправление действует только на новые: рассчитывайте, что история до исправления останется разделённой.
Если не помогло. Проверьте, не пишете ли вы связки из двух окружений в один проект. Тестовый стенд с ключом рабочего проекта создаёт связки настоящих анонимных идентификаторов с тестовыми пользователями, и заметно это становится только на разошедшихся числах.
События с бэкенда не связались с браузерными
Вероятная причина. У серверного события обычно нет anon_id, поэтому
связывать его нечем, кроме user_id. Достаточно расхождения в один символ —
число против строки, префикс, регистр — и в отчётах это два разных человека.
Второй вариант: user_id в серверном событии отсутствует, а anon_id взят
«наугад» — тогда серверное событие остаётся анонимным навсегда.
Как проверить. Найдите в списке событий одно браузерное и одно серверное
событие одного человека и сравните значения user_id посимвольно. Полезная
проверка: постройте отчёт по уникальным пользователям за день по браузерному
событию и по серверному — расхождение в разы обычно и означает разные формы
идентификатора.
Безопасное исправление. Договоритесь об одной канонической форме user_id и
используйте её в обоих местах. Если вам нужна одна сессия для браузерных и
серверных событий, передайте на бэкенд текущий идентификатор сессии из браузера
— приём не умеет сшивать сессии по догадке.
Если не помогло. Есть тонкость с подстановкой. Событию, у которого есть
только anon_id, приём дописывает связанный user_id по кэшу связок, а не по
долговременному хранилищу: запись в кэше живёт 7 дней и продлевается при каждой
новой идентификации. Если человек не входил дольше этого срока, его анонимные
события снова пойдут анонимными — до следующей идентификации. Практический
вывод тот же: где user_id известен, присылайте его в событии.
После выхода события продолжают идти на прежнего пользователя
Вероятная причина. При выходе не вызывается сброс. Тогда сохраняются сразу
две вещи: последний известный user_id в браузере и связка «этот анонимный
идентификатор — этот пользователь» на сервере. Даже если браузерное значение
очистить, события того же анонимного идентификатора будут по-прежнему
приписываться прежнему человеку.
Как проверить. Выйдите из аккаунта и посмотрите хранилище браузера: ключа
pp_user_id быть не должно, а значение pp_anon_id должно измениться. Если
анонимный идентификатор остался прежним, сброс не выполнен.
Безопасное исправление. Вызывайте сброс в обработчике выхода:
pp.reset();
Сброс удаляет pp_user_id, pp_anon_id и pp_session и сразу выдаёт новый
анонимный идентификатор. Новый идентификатор нужен именно для того, чтобы
разорвать существующую связку: сама связка на сервере остаётся, но к ней больше
никто не обращается.
Если не помогло. Помните, что сброс делает и чего не делает:
- он не отменяет связку на сервере и не удаляет историю — это смена субъекта дальнейшего сбора;
- он не выбрасывает события, уже лежащие в очереди отправки: они уйдут с теми идентификаторами, с которыми были созданы;
- он ничего не делает, пока сбор не разрешён согласием.
Удаление данных конкретного человека — отдельная необратимая процедура, а не следствие выхода из аккаунта. См. приватность.
Что проверить
- Запрос на
/v1/identifyуходит при входе и получает202. - В хранилище браузера после входа есть
pp_anon_id,pp_user_idиpp_session, иpp_user_idсовпадает с идентификатором из вашей базы. - После выхода
pp_user_idпропал, аpp_anon_idизменился. - Значение
user_idв браузерном и серверном событии одного человека совпадает посимвольно. - В карточке человека у одного
user_idперечислены все ожидаемые анонимные идентификаторы. - Длина идентификаторов не превышает
256байт — при превышении элемент отклоняется с кодомinvalid_actor, и это видно в ответе, а не в отчётах.
Если склейка настроена правильно, а числа всё равно расходятся, проверьте доставку и повторы: дубли и потери выглядят похоже на проблему идентификации, но лечатся иначе.