Перейти к содержимому
Назад в Академию

Deep linking и deferred deep linking: из рекламы сразу в карточку товара

11.05Мобильная аналитика и атрибуция
Содержание статьи

Приложение доставки продуктов запускает в Instagram рекламу клубники: в объявлении товар и цена, а по нажатию должна открыться его карточка (номера и цифры в уроке условные). Через два дня поддержка пересылает скриншот из чата: человек нажал на клубнику, поставил приложение и попал на главный экран. Искать клубнику он не стал. Маркетолог открывает ту же ссылку на своём iPhone, и карточка на месте. Только у него приложение стоит год, а у человека со скриншота его не было. Это две разные дороги, и ломаются они в разных местах.

Три участка пути

Диплинк (deep link) открывает нужный экран внутри приложения. Отложенный диплинк (deferred deep link) нужен человеку, у которого приложения ещё нет: он проходит через магазин и установку, а при первом запуске видит ту же карточку. По дороге у ссылки три участка, и за каждый отвечает кто-то свой.

УчастокКто отвечаетГде ломается
Ссылка открывает установленное приложениеiOS и Android: универсальная ссылка (Universal Link) и App LinkНет файла на домене, адрес ввели в браузере, приложение-источник не поддерживает такие ссылки
Ссылка переживает установкуMMP или SDK рекламной сетиУстановка позже чем через 15 минут после клика, клик в Meta, iPhone без согласия на отслеживание
Приложение показывает карточкуРазработчикЭкран адреса или входа, товара нет в зоне доставки, неизвестный номер в ссылке

Поэтому на жалобу «диплинк не работает» первый вопрос один: было ли у человека приложение. От ответа зависит, в какой строке искать.

Ссылка: о чём договориться с разработчиком

Ссылки для приложения доставки делают в OneLink, сервисе ссылок AppsFlyer. В ссылке есть параметр deep_link_value, который говорит, какой экран открыть, и deep_link_sub1-deep_link_sub10 для подробностей. AppsFlyer советует заранее договориться о системе значений, чтобы маркетолог мог делать новые ссылки без нового релиза (работа с OneLink). У доставки система такая:

https://grocery-example.onelink.me/Ab12?pid=telegram&c=strawberry_promo&deep_link_value=product&deep_link_sub1=4521

product - тип экрана, 4521 - номер клубники в каталоге. Завтра маркетолог поставит номер арбуза, и разработчик ему для этого не понадобится. По той же схеме category откроет раздел, а promo - страницу акции.

Чтобы ссылка открывала уже установленное приложение, домен и приложение должны подтвердить друг друга. На iOS для этого файл apple-app-site-association на домене и запись applinks в приложении, на Android - App Links и файл assetlinks.json. Для поддомена onelink.me оба файла публикует AppsFlyer, когда в шаблоне ссылки включена переадресация для тех, у кого приложение уже есть (настройка на iOS). Разработчик добавляет домен в приложение, и здесь есть две ловушки:

  • App Links проверяются по отпечатку SHA256 ключа подписи. Приложение в Google Play подписано ключом Play, поэтому отпечаток берут в Play Console, в разделе подписи приложения, а не из тестовой сборки (настройка на Android). С отпечатком тестовой сборки ссылки работают у разработчика и открывают браузер у покупателей.
  • Поддомен OneLink можно сменить в любой момент, но все разосланные ссылки со старым поддоменом перестанут работать.

Если ссылки идут через ваш собственный домен, файлы выкладываете вы. Правила у Apple и Google похожи: HTTPS, никаких переадресаций, свой файл на каждом поддомене (требования Google, разбор ошибок от Apple).

Приложение установлено, а открывается браузер

В той же технической заметке Apple перечисляет случаи, когда универсальная ссылка открывает Safari, хотя настройка верная:

  • Адрес вставили в адресную строку. Это переход внутри браузера, приложение так не откроется никогда.
  • Человек уже на сайте и нажал ссылку на тот же домен: Safari решает, что он хочет остаться в браузере. Кнопке «Открыть в приложении» на сайте нужен отдельный поддомен.
  • Сторонний браузер может не поддерживать универсальные ссылки: это решает его разработчик. AppsFlyer добавляет, что и не каждое приложение их поддерживает, соцсети в том числе.
  • Тестировщик однажды открыл ссылку долгим нажатием и выбрал браузер. iPhone запоминает этот выбор для домена, и дальше все ссылки на нём открываются в Safari, пока тем же долгим нажатием не выберут приложение.
  • Файл на домене поменяли, а телефоны этого не видят. С iOS 14 файл раздаёт CDN Apple, и устройство проверяет обновления примерно раз в неделю. На тестовом телефоне быстрее переустановить приложение.

У рекламы в Meta своё условие: в обычных, не каталожных объявлениях универсальные ссылки и App Links работают только в кампаниях, где местом назначения выбрано приложение (FAQ AppsFlyer по Meta). Кампания с целью «Узнаваемость» (цели рекламы в Meta) с той же ссылкой откроет браузер.

Связь домена с приложением на iPhone видно за минуту. Вставьте ссылку в «Заметки» и нажмите на неё долгим нажатием: если в меню есть и приложение, и браузер, связь настроена. Выберите в меню приложение: что бы вы ни нажали, телефон запомнит это для домена.

Приложения нет: где теряется отложенный диплинк

При первом запуске SDK AppsFlyer забирает с сервера данные клика по OneLink и передаёт их приложению через Unified Deep Linking (UDL). Новому пользователю UDL отдаёт только deep_link_value и deep_link_sub1-deep_link_sub10, а media_source и campaign приходят пустыми (UDL для Android). Экран берут из ответа диплинка, а кампанию из атрибуции, как в аналитике приложения.

UDL не находит клик в трёх случаях (работа с OneLink):

  1. С клика до установки прошло больше 15 минут. Человек нажал на клубнику в автобусе, а поставил приложение вечером дома.
  2. Клик был в самоатрибутирующейся сети (SRN) вроде Meta.
  3. В ссылке нет deep_link_value и deep_link_sub1-deep_link_sub10: например, это старая ссылка, где товар передан своим параметром вроде product_id.

Для первого и третьего случая AppsFlyer советует второй обработчик, расширенный отложенный диплинк (extended deferred deep linking): приложение достаёт параметры ссылки из данных атрибуции при первом запуске. Разработчик отвечает за то, чтобы переход обработал только один из двух методов. С кликом из Meta второй обработчик не поможет, об этом ниже.

На iPhone и у второго обработчика есть предел. AppsFlyer предупреждает, что без IDFA отложенный диплинк через данные атрибуции может не сработать (ATT и SKAN в AppsFlyer), а IDFA пустой у каждого, кто отказал в отслеживании.

С Meta история отдельная. Значений отложенного диплинка из рекламы Meta в данных атрибуции AppsFlyer нет, и чтобы их получить, в приложение обычно ставят SDK Meta (FAQ AppsFlyer по Meta). Сама Meta требует для отложенного диплинка свой SDK и включённый сбор рекламного идентификатора (диплинки в рекламе приложений). На iPhone без согласия этот идентификатор пустой. Такой случай тестируют отдельно и заранее решают, что увидит человек, если карточка не откроется.

Если SDK Meta добавили ради диплинков, события в Meta из него не отправляют: покупки и так уходят туда через AppsFlyer, а события из приложения Meta не дедуплицирует, и покупка посчитается дважды. И предупредите того, кто настраивает SKAN: значения конверсии должен обновлять один SDK, иначе отчёты разойдутся со схемой. Об этом урок про SKAdNetwork.

Внутри приложения: маршрут должен пережить первый запуск

Ссылка дошла, а карточки всё равно нет. При первом запуске приложение доставки просит адрес, чтобы понять, какой склад привезёт заказ, и номер телефона для входа. Если приложение открыло карточку раньше этих экранов, после ввода адреса её заменяет главный экран. На схеме то же самое на примере входа в приложение с уроками.

После входа открыть нужный урок

Приложение с уроками

Ссылка

Урок 4

Маршрут к нужному уроку

Экран входа
Сохранённый маршрут

После входа

  1. Открыт нужный экран

    Урок 4

Вход не должен терять сохранённый маршрут.

Экран входа не должен терять сохранённый маршрут.

Порядок, который стоит записать в задачу разработчику:

  1. Приложение проверяет маршрут: тип экрана из списка (product, category, promo) и номер товара. Неизвестное значение ведёт в каталог или поиск, а не на пустой экран.
  2. Пока человек вводит адрес и телефон, маршрут хранится.
  3. Когда адрес известен, сервер отвечает, есть ли клубника в этой зоне доставки. Если нет, человек видит карточку с пометкой и похожие товары, а не ошибку.
  4. Открытый маршрут удаляется, иначе каждый следующий запуск будет показывать клубнику.
  5. Ссылка задаёт экран, но не даёт прав. Ссылка на заказ 2041 откроет его только владельцу, а пароли, токены и данные карты в ссылки не кладут. Произвольный адрес из параметра ссылки приложение тоже не открывает, иначе ссылкой с вашим доменом человека можно увести на чужой сайт.

Матрица проверки

Перед запуском рекламы клубники разработчик и маркетолог прогнали ссылку на двух телефонах, Android и iPhone, по девяти состояниям:

СостояниеЧто должно открытьсяЧто открылось
Приложение есть, ссылка из TelegramКарточка 4521Карточка
Приложение есть, реклама Meta с приложением в месте назначенияКарточка 4521Карточка
Приложения нет, ссылка из Telegram, установка через 5 минутКарточка после первого запускаКарточка
Приложения нет, ссылка из Telegram, установка через часКарточка после первого запускаГлавный экран: второго обработчика нет
Приложения нет, реклама MetaКарточка после первого запускаГлавный экран: SDK Meta в приложении нет
Первый запуск с экраном адресаКарточка после адресаГлавный экран: маршрут пропал на экране адреса
Клубники нет в зоне доставкиКарточка с пометкой и похожие товарыОшибка загрузки
В ссылке неизвестный номер товараКаталогПустой экран
Адрес вставлен в строку SafariСайтСайт, так и должно быть

Главный экран открылся в трёх строках, и у каждой своё исправление: второй обработчик для поздних установок, SDK Meta для рекламы в Meta и хранение маршрута на экране адреса. С установленным приложением ни одна из этих ошибок не воспроизводится: на телефоне маркетолога карточка открывалась всегда.

Отложенный диплинк проверяют так, как описывает AppsFlyer в руководстве по UDL:

  1. Зарегистрируйте телефон как тестовое устройство, как при приёмке SDK, и включите режим отладки SDK.
  2. Удалите приложение.
  3. Нажмите ссылку, поставьте приложение и откройте его.
  4. В логе SDK найдите результат UDL. NOT_FOUND значит, что ссылка потерялась до приложения. FOUND с признаком отложенного перехода, но без карточки на экране, значит, что она потерялась внутри.
  5. Повторите с установкой через час, на iPhone с разрешением на отслеживание и без него и с рекламой Meta.

Сколько людей доходят до карточки

Тест на двух телефонах показывает, что дорога в принципе работает. Сколько людей по ней проходят, покажут данные. Для этого заведите своё событие, например deep_link_open: такого стандартного события нет ни в Firebase, ни в AppsFlyer, имя мы придумали в уроке. Приложение отправляет его в продуктовую аналитику, когда получает диплинк, с параметрами ссылки и признаком is_deferred, который берут из поля isDeferred в ответе UDL. На карточке уже есть view_item.

Вот что за неделю дал один пост в Telegram-канале сервиса, только Android: там AppsFlyer связывает установку со ссылкой через referrer магазина, и путь виден целиком.

ШагГде смотретьЛюдей
Установили по ссылкеAppsFlyer, источник telegram400
Приложение получило отложенный диплинк на 4521deep_link_open с is_deferred340
Увидели карточку клубникиview_item с товаром 4521 в той же сессии290

До карточки дошли 290 из 400, 72,5%. У 60 человек приложение не получило диплинк или событие не дошло до аналитики, у 50 ссылка потерялась внутри приложения. Почему, по этим цифрам не сказать. Второй обработчик к тому моменту ещё не выпустили, поэтому про первых стоит узнать, сколько из них поставили приложение позже чем через 15 минут после клика. Про вторых - на каком экране закончилась их первая сессия.

С рекламой Meta на iPhone первая строка будет неполной: людей без согласия на отслеживание AppsFlyer, скорее всего, запишет органикой. Можно посчитать только, у какой доли полученных диплинков открылась карточка, и в отчёте так и написать, что в знаменателе полученные диплинки, а не установки из рекламы.

Упражнение: матрица для своего приложения

Возьмите приложение клиента или сервис доставки из урока.

Выполнено 0 из 5

Теперь ситуация из начала урока, только письмом от клиента: «Человек нажал на рекламу клубники, а приложение открыло главную. Диплинки сломаны?»

Отвечать «да» или «нет» рано, сначала нужно понять, было ли у человека приложение. Если было, смотрят первый и третий участок: универсальную ссылку или App Link, место назначения в кампании Meta и маршрутизатор в приложении. Если не было, смотрят путь через установку: получило ли приложение ссылку при первом запуске. Если получило, она потерялась внутри, на экране адреса или на недоступном товаре. Если нет, разбираются, откуда был клик. Из Meta без SDK Meta нужного товара не будет; если с Meta подписано соглашение Advanced Mobile Measurement (AMM), приложение может развести людей только по названию кампании. После 15 минут без второго обработчика диплинка тоже не будет, а на iPhone без согласия на отслеживание его может не быть совсем. В ответе клиенту называют оба сценария и что проверили в каждом: установленное приложение и путь через установку ломаются по разным причинам, и чинят их разные люди.

Видео: как работает deep linking

What is Deep Linking? Learn How it Works (Boost CX & App Conversions)

Вводный ролик AppsFlyer на английском.

Нужна помощь с аналитикой вашего проекта?