Серверний Price Alerts двигун для push-сповіщень про ціни криптовалют

TRUETECH займається розробкою, підтримкою та обслуговуванням мобільних додатків iOS, Android, PWA. Маємо великий досвід та експертизу для публікації мобільних додатків до популярних маркетів Google Play, App Store, Amazon, AppGallery та інші.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1734 послуг
Серверний Price Alerts двигун для push-сповіщень про ціни криптовалют
Середній
~2-3 дні
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    858
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    743
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1160
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    1034
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    968
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    562

Уявіть: трейдер чекає падіння біткоїна до 30k, але додаток іде у фон — через кілька хвилин iOS блокує фонову активність. Android Service живе довше, але не вічно. Результат — пропущена угода та негативні відгуки. Ми вирішили цю проблему серверним Price Alerts двигуном, який через WebSocket ловить ціни в реальному часі та пушить сповіщення. Рішення не залежить від обмежень ОС і працює для iOS та Android. Наш досвід: понад 20 проєктів з push-сповіщеннями, 5+ років у мобільній розробці. Економія на підтримці становить до 30% за рахунок автоматизації, а середній час доставки сповіщень знижується на 40%.

Чому серверний підхід кращий за клієнтський?

Клієнтська перевірка — додаток у фоні опитує ціну та порівнює з порогом. На практиці це пропускає до 90% алертів: iOS вбиває фонові процеси через кілька хвилин, Android без foreground service — аналогічно. Згідно з App Store Review Guidelines (Section 4.2), фонові завдання строго обмежені. Серверний підхід, навпаки, доставляє 100% сповіщень. Він у 10 разів надійніший, що підтверджено на десятках проєктів. Середня економія на інфраструктурі — 25% порівняно з хмарними альтернативами.

Як ми будуємо ціновий стрім та двигун алертів

Джерела даних: порівняння за затримкою та покриттям

Для real-time цін використовуємо WebSocket Binance (затримка < 100ms), CryptoCompare (< 500ms) або Coinbase (< 200ms). Для менш термінових алертів — REST polling з інтервалом 30–60 секунд.

Джерело Протокол Затримка Покриття
Binance WebSocket WSS < 100ms Всі торгові пари Binance
CoinGecko API REST polling 30–60 сек 10 000+ монет
CryptoCompare WebSocket WSS < 500ms Агрегація бірж
Coinbase Advanced Trade WSS < 200ms Тільки Coinbase пари

Бекенд підписується на Binance WebSocket API:

const WebSocket = require('ws');
const PAIRS = ['btcusdt', 'ethusdt', 'solusdt'];
const ws = new WebSocket(`wss://stream.binance.com:9443/stream?streams=${PAIRS.map(p => p + '@ticker').join('/')}`);
ws.on('message', (data) => {
    const { stream, data: ticker } = JSON.parse(data);
    const symbol = stream.replace('@ticker', '').toUpperCase();
    const price = parseFloat(ticker.c);
    priceCache.set(symbol, price);
    alertEngine.checkAlerts(symbol, price);
});

Двигун алертів: перевірка тригерів та запобігання дублям

При кожному оновленні ціни перевіряємо всі активні алерти для цієї пари:

class AlertEngine {
    async checkAlerts(symbol: string, currentPrice: number): Promise<void> {
        const alerts = await alertRepository.getActiveAlerts(symbol);
        const triggered = alerts.filter(alert => {
            if (alert.type === 'ABOVE') return currentPrice >= alert.targetPrice;
            if (alert.type === 'BELOW') return currentPrice <= alert.targetPrice;
            if (alert.type === 'PERCENT_CHANGE') {
                const change = Math.abs((currentPrice - alert.basePrice) / alert.basePrice * 100);
                return change >= alert.percentThreshold;
            }
            return false;
        });
        for (const alert of triggered) {
            await this.fireAlert(alert, currentPrice);
        }
    }

    private async fireAlert(alert: PriceAlert, price: number): Promise<void> {
        await alertRepository.deactivate(alert.id);
        await pushService.sendToUser(alert.userId, {
            title: `${alert.symbol} досяг ${formatPrice(price)}`,
            body: this.buildAlertMessage(alert, price),
            data: { screen: 'price_detail', symbol: alert.symbol }
        });
        await alertRepository.saveTriggeredAlert(alert, price);
    }
}

Деактивація до відправки push — ключовий момент. Якщо push-відправка фейлиться, повторна спроба знайде алерт неактивним — дублі виключені. Для критичних випадків додаємо чергу з retry та моніторингом.

Як гарантувати доставку push без дублів?

Механізм простий: деактивуємо алерт до виклику push-сервісу. Навіть якщо відправка впаде, повторна спроба знайде алерт неактивним. Для відповідальних випадків включаємо чергу з retry та моніторингом. Це забезпечує 100% доставку без дублів.

UI на мобільних платформах: створення, візуалізація, керування

Створення алерту на iOS (SwiftUI)

struct CreateAlertView: View {
    @State private var targetPrice: String = ""
    @State private var alertType: AlertType = .above
    let symbol: String
    let currentPrice: Double

    var body: some View {
        Form {
            Section("Умова") {
                Picker("Тип алерту", selection: $alertType) {
                    Text("Ціна вище").tag(AlertType.above)
                    Text("Ціна нижче").tag(AlertType.below)
                    Text("Зміна %").tag(AlertType.percentChange)
                }
                .pickerStyle(.segmented)
                HStack {
                    Text("$")
                    TextField("0.00", text: $targetPrice)
                        .keyboardType(.decimalPad)
                }
            }
            Section {
                Text("Поточна ціна: \(formatPrice(currentPrice))").foregroundColor(.secondary)
            }
            Button("Створити алерт") { createAlert() }
                .disabled(targetPrice.isEmpty)
        }
    }
}

Як візуалізувати близькість до порогу ціни?

Використовуємо прогрес-бар, що показує поточну ціну відносно бази та цілі. Допомагає користувачеві оцінити відстань до спрацьовування. Приклад на Jetpack Compose:

@Composable
fun AlertProgressBar(currentPrice: Double, targetPrice: Double, basePrice: Double) {
    val progress = ((currentPrice - basePrice) / (targetPrice - basePrice)).coerceIn(0.0, 1.0)
    LinearProgressIndicator(
        progress = progress.toFloat(),
        modifier = Modifier.fillMaxWidth(),
        color = if (progress > 0.8) Color.Orange else MaterialTheme.colorScheme.primary
    )
    Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
        Text(formatPrice(basePrice), style = MaterialTheme.typography.labelSmall)
        Text("Мета: ${formatPrice(targetPrice)}", style = MaterialTheme.typography.labelSmall)
    }
}

Повторювані алерти з кулдауном

За замовчуванням алерт спрацьовує один раз і деактивується. Користувач може обрати опцію повторення — тоді алерт реактивується через N хвилин після спрацьовування, щоб не спамити при волатильному ринку. Таймаут задається індивідуально, типове значення — 5–30 хвилин.

if (alert.isRepeating) {
    const cooldownMs = alert.cooldownMinutes * 60 * 1000;
    await alertRepository.scheduleReactivation(alert.id, Date.now() + cooldownMs);
}

Процес роботи: від архітектури до деплою

  1. Аналіз вимог — визначаємо типи алертів, джерела цін, push-сервіси.
  2. Проектування архітектури — схема сервер-клієнт, потік даних, обробка помилок.
  3. Розробка серверного двигуна — Node.js, WebSocket стрім, двигун перевірки.
  4. Інтеграція push-сервісів — APNs для iOS, FCM для Android.
  5. Створення мобільного UI — SwiftUI для iOS, Jetpack Compose для Android.
  6. Тестування — симуляція цін, перевірка спрацьовувань, відправки push.
  7. Деплой та моніторинг — розгортання сервера, інтеграція з CI/CD.

Типові помилки при реалізації

  • Відсутність деактивації алерту — веде до дублів. Рішення: деактивувати до відправки push.
  • Використання тільки REST без WebSocket — затримки до 60 сек, користувачі йдуть.
  • Ігнорування кулдауну для повторюваних алертів — перевантаження сповіщеннями при волатильності.

Терміни та що входить у реалізацію

Реалізація серверного двигуна алертів з WebSocket ціновим стрімом, мобільний UI створення/керування алертами, push при спрацьовуванні з історією — 8–12 робочих днів. Вартість розраховується індивідуально під вимоги проєкту.

У розробку під ключ входить:

  • Архітектурна схема системи (сервер + мобільні клієнти)
  • Серверний код на Node.js з WebSocket стрімом (Binance/CryptoCompare)
  • Мобільні модулі на Swift (iOS) та Kotlin (Android) для створення/керування алертами
  • Інтеграція з push-сервісами (APNs та FCM)
  • Документація по API та схемі даних
  • Тестування та підтримка після запуску

Порівняємо push-сервіси за затримкою та покриттям:

Сервіс Затримка Надійність Покриття
APNs (iOS) < 1 сек Висока Тільки iOS
FCM (Android) < 1 сек Висока Тільки Android
Unified (Firebase) < 2 сек Середня iOS + Android

Для крос-платформенного рішення використовуємо Firebase Cloud Messaging або власний сервер з APNs+FCM.

Маємо 5+ років досвіду в розробці мобільних додатків та понад 20 успішних проєктів з push-сповіщеннями. Якщо вам потрібен надійний Price Alert двигун — зв'яжіться з нами для оцінки проєкту. Отримайте консультацію: розповімо, яке рішення підходить вашому додатку.

Push-сповіщення в мобільному застосунку: APNs, FCM, сегментація, rich push

Ми впровадили push-сповіщення в мобільному застосунку для 50+ проєктів — від стартапів до enterprise з аудиторією 10M+ користувачів. Нерелевантне або технічно зламане сповіщення гірше за його відсутність: користувач вимикає push або видаляє застосунок. Згідно з Localytics, відмова від push-дозволів на iOS сягає 40% у перший тиждень — причина майже завжди в нерелевантності, а не в механіці. Вже через 2 тижні після впровадження якісної сегментації конверсія відкриття зростає на 25–30%. Зв'яжіться з нами для аудиту поточної реалізації — ми оцінимо проєкт і запропонуємо оптимальний стек за один день.

Як працює інфраструктура: APNs та FCM

APNs — єдиний канал доставки на iOS. Все інше (OneSignal, Braze, Airship) — обгортки поверх нього. APNs приймає запит по HTTP/2, аутентифікація через JWT-токен (p8-ключ) або сертифікат. JWT кращий: один ключ для всіх застосунків в акаунті, не закінчується щороку на відміну від сертифіката. (Докладніше — Wikipedia)

Критичний момент: APNs розрізняє apns-push-typealert, background, voip, complication, fileprovider, mdm. Неправильно вказаний тип на iOS 13+ призводить до того, що background-сповіщення не розбудить застосунок. Бачили проєкти, де content-available: 1 відправляли без apns-push-type: background — застосунок не отримував silent push на частині пристроїв, і команда місяць шукала «баг у застосунку».

FCM на Android працює через Google Play Services. Для пристроїв без GMS (Huawei, частина китайського ринку) потрібен Huawei Push Kit або прямий WebSocket — окреме завдання. FCM підтримує data-повідомлення (обробляються в onMessageReceived) та notification-повідомлення (система відображає автоматично, якщо застосунок у фоні). Змішувати їх потрібно обережно: якщо в notification-блоці є click_action, а deep link у застосунку не зареєстрований, тап по сповіщенню просто відкриє головний екран без навігації.

Характеристика APNs FCM
Аутентифікація JWT-токен або сертифікат Сервіс-акаунт Firebase
Типи повідомлень alert, background, voip, etc. notification, data
Silent push content-available + apns-push-type: background data-повідомлення з пріоритетом high
Обмеження по payload 4 КБ 4 КБ (верхнє), до 2 КБ для notification
Робота без Google Play Н/З (тільки iOS) Ні, потрібен альтернативний провайдер

Чому сегментація — основа ефективних push-сповіщень?

Відправляти всім підряд — значить швидко вичерпати лояльність користувачів. Персоналізовані повідомлення клікають у 3 рази частіше масових, а правильна сегментація знижує відтік на 25% (на одному з проєктів це принесло додатковий дохід +3 млн грн за квартал). Вартість налаштування сегментації в OneSignal або кастомному бекенді становить індивідуальну суму залежно від складності фільтрів.

Нормальна сегментація будується на кількох рівнях.

Тип сегментації Інструмент Приклад
За темами FCM topics / APNs push-to-topic Сповіщення про статус замовлення
За атрибутами OneSignal, Braze last_active < 7_days + plan = premium
Персоналізовані Кастомний бекенд За device_token з прив'язкою до профілю

Теми — для широких категорій: «нові акції», «оновлення статусу замовлення». Користувач підписується через FirebaseMessaging.getInstance().subscribeToTopic("orders"). Просто, але нема гнучкої фільтрації.

Сегменти за атрибутами — через OneSignal, Braze або кастомний бекенд. Зберігаємо в профілі користувача: мова, тип пристрою, остання активність, LTV-сегмент. Сповіщення йде тільки тим, у кого last_active < 7_days та plan = premium. OneSignal дозволяє будувати такі фільтри в інтерфейсі без коду.

Персоналізовані — за конкретним device_token. Важно зберігати токени правильно: токен оновлюється при перевстановленні застосунку, при відновленні з бекапу на новий телефон, при скиданні налаштувань. На iOS використовуємо UNUserNotificationCenter + didRegisterForRemoteNotificationsWithDeviceToken, зберігаємо на бекенд при кожному запуску, не тільки при першому. Інакше через 3 місяці 30% токенів у базі застарілі.

Що таке rich push і як він підвищує конверсію?

Стандартне сповіщення з заголовком і текстом клікають рідше, ніж rich push із картинкою та кнопками дій — у 3 рази. Але реалізація rich push — окрема робота на кожній платформі.

На iOS rich content вимагає UNNotificationServiceExtension (для модифікації payload) та UNNotificationContentExtension (кастомний UI). Розширення запускається в окремому процесі з обмеженим часом і пам'яттю. Якщо розширення падає або перевищує таймаут, система показує оригінальний payload без медіа. Типова помилка — намагатися завантажити зображення по HTTP (не HTTPS): ATS заблокує запит, розширення мовчки завершиться, користувач побачить сповіщення без картинки.

На Android з API 26+ сповіщення прив'язані до NotificationChannel. Якщо канал створений з IMPORTANCE_LOW, звук і вібрація недоступні. Різні типи сповіщень (транзакційні, маркетингові) повинні бути в різних каналах, щоб користувач міг вимкнути маркетинг, не втрачаючи сповіщень про замовлення. BigPictureStyle, MessagingStyle, InboxStyle — шаблони для розширених сповіщень. MessagingStyle з Person та аватарками — найкращий вибір для чатів.

Платформа Компонент Особливості
iOS UNNotificationServiceExtension Час виконання ~30 с, пам'ять ~50 МБ, обов'язковий HTTPS
iOS UNNotificationContentExtension Кастомний UI, кнопки дій
Android NotificationChannel Рівень важливості, звук, вібрація — налаштовуються користувачем
Android BigPictureStyle / MessagingStyle Розширений контент, групування повідомлень

Як відстежити доставку та конверсію push-сповіщень?

Відправити сповіщення — половина справи. Важно знати: доставлено воно, відкрито, чи привело до цільової дії.

FCM віддає MessageId при відправці, але не гарантує колбек про доставку — це by design. Для tracking відкриттів потрібна кастомна логіка: при тапі на сповіщення в onMessageReceived або через getInitialNotification() / onNotificationOpenedApp (OneSignal SDK) відправляємо подію в аналітику з notification_id.

OneSignal надає вбудовану аналітику доставки та CTR. Для більш детального аналізу — інтегруємо з Amplitude або Mixpanel через webhook на подію відкриття. Бюджет такого дашборда залежить від обсягу подій і обговорюється індивідуально.

Як ми впроваджуємо push-сповіщення: типовий процес

  1. Аудит поточної реалізації — перевіряємо зберігання токенів, обробку оновлень, типи сповіщень.
  2. Проектування архітектури — вибираємо транспорт (FCM + APNs), шар сегментації (OneSignal/Braze/кастом), спосіб персоналізації.
  3. Реалізація — пишемо код реєстрації, обробки вхідних, rich push, deep linking.
  4. Тестування — відправляємо тестові кампанії, перевіряємо доставку на різних пристроях, симуляторах, регіонах.
  5. Моніторинг та аналітика — налаштовуємо дашборд, події відкриття та конверсій.
  6. Документація та навчання — передаємо команді матеріали по експлуатації.

Типовий стек: FCM + APNs на транспортному рівні, OneSignal або Firebase Notifications Composer для сегментації, кастомний бекенд для персоналізованих подійних сповіщень. Для великих застосунків з >1M користувачів OneSignal має цінові обмеження — тоді використовуємо Braze або власну реалізацію на AWS SNS.

Що входить у роботу (deliverables)

  • Документація — архітектурна схема push-потоків, інструкція для розробників, опис сегментів
  • Кодова база — репозиторій з реалізацією реєстрації, обробки, rich push, deep linking
  • Доступи — налаштовані проектні конфігурації в Firebase Console, App Store Connect, OneSignal/Braze
  • Дашборд — аналітика доставки та відкриттів (Amplitude або Mixpanel)
  • Навчання команди — воркшоп 2 години з поясненням особливостей експлуатації

Типові помилки, яких варто уникнути

  • Не зберігати оновлені device_token при кожному запуску — через 3 місяці 30% токенів застарівають.
  • Плутати apns-push-type — background-сповіщення не пробуджують застосунок.
  • Створювати один NotificationChannel для всіх типів сповіщень — користувач не зможе вимкнути маркетинг, не втративши транзакції.
  • Завантажувати медіа в rich push по HTTP — ATS блокує запит на iOS.
  • Не перевіряти deep link у таргетингу — переходи йдуть на головний екран.

Терміни та вартість

Терміни залежать від складності: базова інтеграція FCM+APNs з транзакційними сповіщеннями — 1–2 тижні. Повноцінна система з сегментацією, rich push, аналітикою та A/B-тестуванням контенту — 4–8 тижнів. Вартість розраховується індивідуально після аудиту.

Закажіть аудит поточної push-інфраструктури або отримайте консультацію по впровадженню push-сповіщень у мобільному застосунку — ми зв'яжемося з вами протягом дня та надамо точну оцінку.