Інтеграція SMS-рассилки в мобільний додаток
SMS-рассилка в мобільному додатку — це серверна завдача. Клієнт тільки ініціює запит: «відправити сповіщення користувачам X, Y, Z». Все інше — HTTP-запит на бекенд або напрямку до SMS-шлюза. Тому мобільна частина невелика, зато серверна потребує акуратного проектування.
Вибір шлюза
Найбільш розповсюджені варіанти:
| Шлюз | Плюси | Мінуси |
|---|---|---|
| Twilio | REST API, webhooks, глобальний охват | Дороже аналогів для СНГ |
| SMSC.ru / SMS-шлюз.ру | Дешево для РФ/СНГ | Нема webhook-сповіщень про статус у ряду тарифів |
| Infobip | Multichannel (SMS + Viber + WhatsApp) | Складний onboarding |
| Vonage (Nexmo) | SDK для мобільних, верифікація номерів | Обмежений охват за СНГ |
Для типового B2C-додатка з аудиторією в СНГ — SMSC або аналогічний локальний шлюз. Для міжнародного — Twilio або Infobip.
Серверна частина: що важливо реалізувати
Отправка SMS через Twilio — один HTTP-запит:
POST https://api.twilio.com/2010-04-01/Accounts/{AccountSid}/Messages
Authorization: Basic {base64(AccountSid:AuthToken)}
Content-Type: application/x-www-form-urlencoded
To=%2B380991234567&From=%2B14155551234&Body=Ваш+заказ+готовий
Але bulk-рассилка — це черга, не прямі вызови в цикл. Одночасна отправка 10 000 сообщень через синхронні HTTP-запити убье і бекенд, і бюджет (rate limiting шлюза). Правильна схема: черга завдань (RabbitMQ, Redis + BullMQ, SQS), воркери з throttling за rate limit шлюза.
Twilio rate limit — до 100 SMS/сек на коротком номері (Short Code), 1 SMS/сек на звичайному (Long Code). На звичайний номер — воркери повинні дотримуватися цього обмеження.
Мобільний клієнт: що реалізується
На мобільній стороні потрібно:
- Форма складання сообщення — з підрахунком символів (160 для Latin, 70 для Cyrillic, конкатенація при перевищенні).
- Вибір сегмента отримувачів — через готовий API бекенда.
- Запуск рассилки — POST-запит з параметрами.
- Відстеження статусу — polling або WebSocket/SSE для real-time прогресу.
// iOS — отправка запиту на рассилку
struct BulkSmsRequest: Codable {
let segmentId: String
let message: String
let scheduledAt: Date?
}
func sendBulkSms(_ request: BulkSmsRequest) async throws -> BulkSmsJob {
let response = try await apiClient.post("/admin/sms/bulk", body: request)
return try response.decode(BulkSmsJob.self)
}
Символьний счётчик — важна деталь UX. SMS розбивається на частини при перевищенні лімітові, кожна частина тарифікується окремо:
fun countSmsPartsAndChars(text: String): SmsInfo {
val isGsm7 = text.all { it.isGsm7Char() }
val maxPerPart = if (isGsm7) 160 else 70
val maxConcatenated = if (isGsm7) 153 else 67
return if (text.length <= maxPerPart) {
SmsInfo(parts = 1, charsUsed = text.length, charsPerPart = maxPerPart)
} else {
val parts = ceil(text.length.toDouble() / maxConcatenated).toInt()
SmsInfo(parts = parts, charsUsed = text.length, charsPerPart = maxConcatenated)
}
}
Статусы доставки
Twilio відправляє webhook на ваш сервер при зміні статусу кожного сообщення: queued → sending → sent → delivered або undelivered / failed. Бекенд агрегує статусы, мобільний клієнт запитує зводку:
GET /admin/sms/jobs/{jobId}/stats
→ { "total": 5000, "sent": 4823, "delivered": 4601, "failed": 177 }
Терміни
Інтеграція SMS-шлюза (Twilio або SMSC), реалізація черги рассилки, мобільний UI з счётчиком символів, вибором сегмента та відстеженням прогресу — 5–8 робочих днів.







