Справочник событий
Каждый вызов, который предлагает SDK, на каждой платформе, с именем события, которое попадает в Unolink. Воронки задаются для каждого приложения: создавайте сколько угодно в разделе Воронка → Новая воронка и выбирайте любые из этих имён как шаги, включая ваши собственные. Каждый шаг учитывает установки, которые отправили событие в любое время, поэтому даже у приложений, где экраны идут в другом порядке, воронка получается осмысленной. Включите в воронке Учитывать шаги только в этом порядке, чтобы шаг засчитывался, только когда он происходит после предыдущего.
Стандартные события
| Имя события | Android | iOS | React Native | Flutter | Шаг воронки |
|---|---|---|---|---|---|
onboarding_step | onboardingStep(step, index, flow) | onboardingStep(_:index:flow:) | onboardingStep(step, { index, flow }) | onboardingStep(step, index:, flow:) | Вкладка «Онбординг», не шаг |
onboarding_skipped | onboardingSkipped(step) | onboardingSkipped(_:) | onboardingSkipped(step) | onboardingSkipped(step) | Вкладка «Онбординг», не шаг |
onboarding_completed | onboardingCompleted() | onboardingCompleted() | onboardingCompleted() | onboardingCompleted() | Онбординг |
paywall_viewed | paywallViewed(placement) | paywallViewed(placement:) | paywallViewed(placement) | paywallViewed(placement:) | Пейволл |
paywall_skipped | paywallSkipped(placement) | paywallSkipped(placement:) | paywallSkipped(placement) | paywallSkipped(placement:) | Если вы его добавите |
sign_up | signUp(method) | signUp(method:) | signUp(method) | signUp(method:) | Регистрация |
sign_in | signIn(method) | signIn(method:) | signIn(method) | signIn(method:) | Вошли в аккаунт |
sign_up_skipped | signUpSkipped() | signUpSkipped() | signUpSkipped() | signUpSkipped() | Продолжили как гость |
trial_started | trialStarted(productId) | trialStarted(productId:) | trialStarted(productId) | trialStarted(productId:) | Пробный период |
purchase | purchase(amount, currency, productId) | purchase(amount:currency:productId:) | purchase(amount, currency, productId) | purchase(amount, currency, productId:) | Оплатил |
purchase_cancelled | purchaseCancelled(productId) | purchaseCancelled(productId:) | purchaseCancelled(productId) | purchaseCancelled(productId:) | Если вы его добавите |
purchase_failed | purchaseFailed(productId, reason) | purchaseFailed(productId:reason:) | purchaseFailed(productId, reason) | purchaseFailed(productId:reason:) | Если вы его добавите |
| ваше собственное | track(name, properties) | track(_:properties:) | track(name, properties) | track(name, properties) | Если вы его добавите |
Все аргументы, кроме суммы и валюты покупки, необязательны, и каждый вызов также принимает дополнительные свойства.
placementуказывает, какой это пейволл:onboarding,launch,feature_gate,settingsили ваше собственное название. Отправляется как свойствоplacement. Воронка → разбивка по пейволлу показывает отдельную воронку для каждого placement.methodуказывает, как был создан аккаунт:email,apple,google. Отправляется какmethod.productId— ID продукта в вашем магазине. Отправляется какproduct_id.purchaseпередаёт цену в виде десятичного числа (Android —BigDecimal, iOS —Decimal, React Native и Flutter — строка вроде"49.99") и трёхбуквенный код валюты. Цены никогда не округляются.
Когда отправлять каждое
| Событие | Когда отправлять |
|---|---|
onboarding_step | Когда каждый экран онбординга появляется, а не когда нажимают его кнопку. См. Экраны онбординга. |
onboarding_skipped | Когда человек нажимает «Пропустить», с экраном, на котором он это сделал. |
onboarding_completed | Когда последний вопрос или экран онбординга пройден, до пейволла или регистрации, которые идут после него. |
paywall_viewed | Каждый раз, когда появляется пейволл, с его placement. Не для подписчиков: если ваше приложение не показывает им пейволл, ничего не отправляйте. |
paywall_skipped | Когда человек закрывает пейволл, ничего не купив: кнопкой закрытия, свайпом вниз или жестом «назад». Не пока покупка ещё ждёт подтверждения (Ask to Buy, проверка 3-D Secure в банке). |
sign_up | Сразу после создания нового аккаунта. Не когда человек входит в аккаунт, который у него уже был. |
sign_in | Когда человек входит в аккаунт, который у него уже был: вернувшийся пользователь (переустановка, новый телефон, после выхода из аккаунта). «Пути» помечают его как вернувшегося и умеют по этому фильтровать. SDK 0.3.0 и новее. |
sign_up_skipped | Когда человек на экране регистрации решает продолжить без аккаунта (гостевой режим). «Пути» помечают его как гостя, а воронка с шагом регистрации показывает его как пошедшего другим путём, а не как отвалившегося. |
trial_started, purchase | Когда магазин это подтверждает. Не отправляйте ни то, ни другое, если подключён RevenueCat. |
purchase_cancelled | Когда человек закрывает окно покупки магазина, не заплатив. |
purchase_failed | Когда оплата не прошла. reason — ваше собственное краткое описание. |
Экраны онбординга
Вкладка Онбординг показывает, на каком экране люди уходят и сколько времени занимает каждый. Отправляйте по одному вызову на
экран, когда он появляется, один при нажатии «Пропустить» и onboardingCompleted в конце:
// iOS (SwiftUI)
GoalScreen().onAppear { Unolink.onboardingStep("goal", index: 0) }
Button("Skip") { Unolink.onboardingSkipped("goal") }
// Android (Compose)
LaunchedEffect(Unit) { Unolink.onboardingStep("goal", index = 0) }
// React Native
useOnboardingStep("goal", { index: 0 }) // or Unolink.onboardingStep("goal", { index: 0 }) in a useEffect
// Flutter, in initState
Unolink.onboardingStep('goal', index: 0);
step— постоянный ID экрана:goal,notifications,plan. Те же правила, что и для имён событий. Давайте ветвлениям собственные ID. Пейджер или онбординг на одном экране отправляет по одному на страницу.- Только собственные экраны онбординга. Пейволл и экран регистрации не являются экранами онбординга, даже когда они
входят в тот же сценарий: они отправляют
paywallViewed/paywallSkippedиsignUp. Пейволл, закрытый без покупки, — этоpaywallSkipped, а неonboardingSkipped. onboardingCompletedотправляется сразу после последнего экрана онбординга, до пейволла или регистрации, которые идут дальше, даже если аккаунт создаётся в конце сценария. Тот, кто видит пейволл, уже прошёл онбординг.index(необязательно) — позиция экрана, от 0 до 999. С ним вкладка может показать самый дальний достигнутый экран, а не только последний увиденный.flow(необязательно) задаёт название онбординга, когда у вас их несколько: вариант A/B-теста, новая версия, повторный онбординг. У каждого flow свой список.- Других свойств эти события не принимают. С любыми другими событие отклоняется.
- Никогда не передавайте данные пользователя в
stepилиflow. Это названия экранов, которые показываются в панели. - Они бесплатны. Онбординг стоит одно событие, свой
onboardingCompleted, сколько бы в нём ни было экранов. Каждая установка может отправить до 100 таких событий, для не более чем 40 разных экранов. - Навигация назад, принудительное закрытие приложения и перезапуски не требуют ничего особенного. Unolink сам определяет статус
каждой установки: завершил, пропустил на каком-то экране, ушёл на своём последнем экране (ничего нового 24 часа) или ещё
проходит. Приложение, которое отправляет только
onboardingCompleted, всё равно показывает, сколько людей завершили онбординг; экраны нужны, чтобы увидеть, где люди уходят. Установки, которые не отправили ни одного события онбординга, показываются как неотслеживаемые, а не как отвалившиеся.
Для этих вызовов нужен SDK 0.2.0 или новее. В старых версиях то же событие отправляет track("onboarding_step", { step: "goal" }).
Как учитываются события
- Воронки считают людей, а не события. Каждый шаг учитывает установки, которые отправили событие хотя бы один раз, поэтому
пейволл, увиденный пять раз, или
onboardingCompleted, отправленный снова после возврата назад, учитывается один раз на человека. - По умолчанию — в любом порядке. Шаг засчитывается, когда бы он ни произошёл. Включите в воронке Учитывать шаги только в этом порядке, когда порядок важен; тогда шаг засчитывается, только если он произошёл одновременно с предыдущим или после него.
- Каждое событие всё равно учитывается в вашем тарифе. Повторы записываются («Пути» показывают каждый) и каждый учитывается в месячном лимите, кроме бесплатных событий ниже.
- Время берётся с телефона, если только оно не старше 7 дней и не больше чем на час в будущем; тогда используется время получения события.
Гости и аккаунты
Сообщайте собственный app user ID RevenueCat каждый раз, когда он меняется: для гостя — анонимный ID RevenueCat, затем ID
аккаунта, который человек создаёт или в который входит. connectRevenueCat (SDK 0.3.2 и новее) делает это за вас; иначе вызывайте
с ним setUserId. Учитываются все ID, которые сообщала установка, поэтому покупка, сделанная гостем, её продления и покупки,
которые RevenueCat позже переносит на другой аккаунт, остаются у той установки, которая купила.
| Что произошло | Что отправить |
|---|---|
| Создан новый аккаунт (email, Apple, Google, в том числе после гостевого режима) | signUp(method) |
| Вход в аккаунт, который уже был | signIn(method) |
| Решил продолжить без аккаунта | signUpSkipped() (SDK 0.3.2+, React Native 0.3.1+; в старых SDK: track("sign_up_skipped")) |
| Гость регистрируется позже, из настроек | signUp(method): это засчитывается для шага регистрации в воронке, когда бы ни произошло |
| Вход со сброшенным паролем | signIn(method): аккаунт уже существовал |
| Попытка зарегистрироваться с уже зарегистрированным email, затем вход | signIn(method) |
| Выход из аккаунта | setUserId(null) |
Новый или вернувшийся пользователь при входе через Apple или Google? Обычно это видно из результата входа. Firebase:
additionalUserInfo.isNewUser. Supabase: пользователь, у которого created_at отличается от last_sign_in_at на несколько
секунд, только что создан.
Автоматические события
Их SDK отправляет сам. Они бесплатны: они никогда не учитываются в вашем тарифе.
| Событие | Когда |
|---|---|
first_open | Один раз на установку, при первом запуске. Это и есть установка. |
session_start | При запуске или когда приложение возвращается после 30 минут или более в фоне. |
app_background | Когда приложение уходит в фон. |
Собственные события
track(name, properties) отправляет всё остальное, и собственные события тоже могут быть шагами воронки.
- Имена: начинаются с латинской буквы, затем латинские буквы, цифры,
_и., не длиннее 64 символов.level_upилиexport.pdf. Недопустимое имя отбрасывается и записывается в лог. - Свойства: не больше 20 на событие. Значения — строки (до 200 символов), числа или логические значения, всего 4 КБ.
- Никогда не передавайте в свойствах имена, email, номера телефонов или другие персональные данные.
Состояние пользователя и приложения
Эти вызовы не отправляют собственного события.
| Android | iOS | React Native | Flutter | Что делает |
|---|---|---|---|---|
setUserId(id) | setUserId(_:) | setUserId(id) | setUserId(id) | ID пользователя вашего приложения; с RevenueCat — собственный app user ID RevenueCat. Хранится только в виде одностороннего хеша, своего для каждого приложения. Вызывайте снова каждый раз, когда он меняется (гость → аккаунт): учитывается каждый ID. При выходе из аккаунта передавайте null (nil). Не длиннее 256 символов. |
connectRevenueCat { } | connectRevenueCat { } | connectRevenueCat(Purchases) | connectRevenueCat(…) | Поддерживает ID пользователя равным app user ID RevenueCat, включая гостей (SDK 0.3.2+). См. RevenueCat. Используйте его или setUserId, но не оба. |
revenueCatUserChanged() | revenueCatUserChanged() | Сразу отправляет новый ID RevenueCat: вызывайте после logIn и logOut (SDK 0.3.2+). React Native и Flutter замечают смену сами. | ||
setDeferredDeepLinkListener { } | onDeferredDeepLink(_:) | addDeferredDeepLinkListener(fn) | setDeferredDeepLinkListener(fn) | Вызывается один раз для каждой установки, пришедшей по ссылке Unolink. На практике только Android. |
getPendingDeferredDeepLink(), consumeDeferredDeepLink() | getPendingDeferredDeepLink(), consumeDeferredDeepLink() | getPendingDeferredDeepLink(), consumeDeferredDeepLink() | Ссылка, которую нужно открыть после завершения онбординга или входа, а затем отметить как открытую. Она ждёт, пока её не используют, даже если приложение за это время закрывали, до 30 дней (SDK 0.3.3+; React Native 0.3.1+ хранил её в течение одного запуска). | |
isConfigured() | Был ли выполнен configure с ключом (React Native 0.3.1+). | |||
getInstallId() | installId | getInstallId() | getInstallId() | Случайный ID этой установки. |
flush() | flush() | flush() | flush() | Отправляет события из очереди прямо сейчас. |
setEnabled(bool) | setEnabled(_:) | setEnabled(bool) | setEnabled(bool) | Отключает отслеживание (события из очереди удаляются) или включает его снова. |
RevenueCat
Когда RevenueCat подключён, он становится источником истины для денег. Он сообщает о пробных периодах, покупках,
продлениях, отменах, возвратах, истечении подписок и проблемах с оплатой, даже когда приложение не открыто. Вызовы
purchase и trialStarted из приложения игнорируются, поэтому ничего не учитывается дважды. Вашему приложению нужен только
connectRevenueCat (или setUserId с ID из RevenueCat).
Квота тарифа
SDK входит в тарифы Pro и Studio. Каждое событие, которое отправляет ваше приложение, учитывается в месячном лимите
событий: 1 миллион на Pro, 5 миллионов на Studio. Сюда входят стандартные события выше и ваши собственные.
Автоматические события (first_open, session_start, app_background) и экраны онбординга
(onboarding_step, onboarding_skipped) бесплатны, как и покупки, продления и возвраты, которые приходят из RevenueCat. Превышение
лимита ничего не блокирует; при превышении лимита вдвое собственные события отклоняются до следующего месяца, а стандартные события,
события онбординга и автоматические события сохраняются всегда.