Налаштування персоналізації push-сповіщень у мобільному додатку
Сповіщення «Привіт, {{ім'я}}!» — це не персоналізація. Справжня персоналізація — це коли користувач отримує повідомлення про знижку саме на ту категорію товарів, яку переглядав три дні тому, у той час дня, коли він зазвичай відкриває додаток. Розберемо, як це реалізується технічно.
Динамічні змінні у payload
Будь-яка серйозна платформа — OneSignal, Braze, CleverTap, Firebase + власний бекенд — підтримує шаблони зі змінними. Серверна сторона рендерить фінальний текст перед відправкою.
У OneSignal це виглядає на рівні API:
{
"app_id": "YOUR_APP_ID",
"include_aliases": { "external_id": ["user_88234"] },
"headings": { "ru": "{{first_name}}, ваш избранный товар подешевел" },
"contents": { "ru": "{{product_name}} теперь стоит {{new_price}} ₴ — на {{discount_percent}}% меньше" },
"data": { "product_id": "{{product_id}}", "screen": "product_detail" }
}
Значення змінних беруться з тегів користувача у OneSignal або передаються у substitutions при відправці через API. Тег first_name повинен бути встановлений заздалегідь на клієнті:
OneSignal.User.addTag("first_name", user.firstName)
OneSignal.User.addTag("preferred_category", user.topCategory)
Персоналізація на основі поведінки
Це складніше — вимагає аналітичного шару на бекенді. Типова схема:
- Клієнт логірує события (перегляд товару, додавання у wishlist, категорія).
- Бекенд або ML-сервіс формує рекомендації для користувача.
- При відправці сповіщення payload збагачується рекомендованим контентом.
Якщо немає власного рекомендаційного рушія — можна використовувати Firebase Personalization (ML-базована оптимізація контенту A/B тестів) або Braze Recommendations, які будують модель на основі історії подій SDK.
// Логуємо поведінку через Firebase Analytics
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.VIEW_ITEM) {
param(FirebaseAnalytics.Param.ITEM_ID, product.id)
param(FirebaseAnalytics.Param.ITEM_CATEGORY, product.category)
param(FirebaseAnalytics.Param.PRICE, product.price)
}
Оптимальний час відправки (Intelligent Delivery)
OneSignal Intelligent Delivery та Braze Optimal Time відстежують паттерни активності кожного користувача та відкладають доставку до періоду найбільшої ймовірності відкриття. Для одного користувача це 8 ранку, для іншого — 23:00.
Включається одним параметром при відправці:
{
"delayed_option": "last-active",
"delivery_time_of_day": "9:00AM"
}
last-active — доставити у той же час дня, коли користувач останній раз був активен. Це не ML, але вже краще за batch-рассилку в одний час для всіх.
Більш точний варіант у OneSignal — intelligent_delivery: true. Платформа сама вибирає вікно за історією open rate конкретного користувача.
A/B тестування
Без A/B нельзя стверджувати, що персоналізація працює. OneSignal підтримує A/B тести нативно:
{
"name": "price_drop_ab_test",
"messages": [
{
"variant_id": "A",
"contents": { "ru": "{{product_name}} подешевел на {{discount}}%" },
"weight": 50
},
{
"variant_id": "B",
"contents": { "ru": "Скидка {{discount}}% на товар из вашего вишлиста" },
"weight": 50
}
]
}
Після завершення тесту OneSignal показує CTR за кожним варіантом. Переможець використовується у шаблоні.
Відстеження конверсій
CTR сповіщення — проміжна метрика. Важливіше — чи дійсно користувач завершив дію? Для цього потрібні outcome events:
// У обробнику відкриття сповіщення
OneSignal.Notifications.addClickListener { event ->
val productId = event.notification.additionalData?.getString("product_id")
// Користувач перейшов до товару
OneSignal.Session.addOutcome("notification_click_to_product")
}
// Після завершення покупки (в іншому місці коду)
OneSignal.Session.addOutcomeWithValue("purchase_from_notification", orderValue.toFloat())
Це пов'язує конверсію зі конкретним сповіщенням навіть якщо між кліком та покупкою пройшло кілька хвилин.
Терміни
Реалізація динамічних змінних та шаблонів, налаштування Intelligent Delivery, інтеграція outcome events та базового A/B тестування — 6–10 робочих днів. Якщо потрібен власний рекомендаційний шар на бекенді або інтеграція з зовнішньою ML-системою — терміни обговорюються окремо.







