Реалізація мультиканального бота (Telegram + WhatsApp + Viber) у мобільних додатках
Інтегрувати бота в одному мессенджері просто. Складність починається, коли потрібно охопити Telegram, WhatsApp та Viber одночасно — і при цьому не перетворити кодову базу на три незалежних купи логіки. Головна архітектурна задача: єдиний шар бізнес-логіки, а специфіку кожної платформи ізолювати за інтерфейсом адаптера.
Чому три боти — це не у три рази більше роботи, а у три рази більше помилок
Кожна платформа живе за своїми правилами. Telegram Bot API відправляє вебхук синхронно та очікує відповідь 200 OK протягом 5 секунд — якщо бекенд поривається, платформа починає повторювати запити, і бот отримує дублікати. WhatsApp Business API (Meta Cloud API) працює інакше: вебхук для верифікації приходить GET-запитом з hub.challenge, і якщо не відповісти правильним значенням, вебхук просто не реєструється — тиха помилка, яку легко пропустити.
Viber відрізняється форматом rich media: тип rich_media з кнопками працює тільки при відправленні через send_message, а не через reply API. Розробники, які переносять логіку з Telegram (де inline keyboard вішається прямо на будь-яке повідомлення), натикаються на це в перший же день.
Окрема історія — формат вкладень. Telegram приймає multipart/form-data при відправленні файла напрямо, WhatsApp вимагає спочатку завантажити медіа через POST /v1/media та отримати media_id, і тільки потім надіслати його у повідомленні. Viber обмежує розмір файла 200 МБ та підтримує суворо визначені MIME-типи.
Якщо вся ця логіка розтягнута по одному сервісу без чіткої абстракції, супровід цього через півроку неможливий.
Архітектура: один канал обміну, три адаптери
Правильний підхід — ввести інтерфейс BotAdapter з методами sendMessage, sendFile, parseIncoming. Кожна платформа — своя реалізація.
// Android (Kotlin) — приклад адаптивного шару
interface BotAdapter {
suspend fun sendMessage(chatId: String, text: String, buttons: List<BotButton>? = null)
suspend fun sendFile(chatId: String, fileUrl: String, mimeType: String)
fun parseIncoming(payload: String): BotMessage
}
class TelegramAdapter(private val token: String) : BotAdapter {
private val client = OkHttpClient()
override suspend fun sendMessage(chatId: String, text: String, buttons: List<BotButton>?) {
val body = buildTelegramPayload(chatId, text, buttons)
client.newCall(Request.Builder()
.url("https://api.telegram.org/bot$token/sendMessage")
.post(body).build()).execute()
}
// ...
}
На iOS паттерн той же — протокол BotAdapter та три struct-реалізації через URLSession. У Flutter зручно використовувати абстрактний клас з dio під капотом.
Бізнес-логіка (розпізнавання команд, FSM діалогу, робота з базою) живе вище — вона не знає, звідки прийшло повідомлення.
Управління станом діалогу
Для будь-якого нетривіального бота потрібна машина кінцевих станів. Зберігання userState в пам'яті — антипаттерн: при перезавантаженні сервісу всі діалоги скидаються. На практиці використовуємо Redis з TTL (наприклад, 30 хвилин неактивності скидають сесію) або таблицю в PostgreSQL з updated_at.
Ключ стану — {platform}:{chatId}, це дозволяє одному користувачеві мати незалежні діалоги в різних мессенджерах, що іноді потрібно за бізнес-логікою.
Специфіка мобільного додатка
Якщо бот вбудовується не в серверний сервіс, а безпосередньо в мобільний додаток — потрібна WebSocket-підписка або polling. Для Telegram у мобільному контексті це getUpdates з long polling через BackgroundFetch (iOS) або WorkManager (Android). Тримати постійний WebSocket для бота у фоні iOS не дасть — система вбиває процес. Правильний паттерн: push-сповіщення від сервера будить додаток, він робить один getUpdates, обробляє чергу та засипає.
WhatsApp Cloud API у мобільному додатку вимагатиме серверного прокси — викликати Meta API напрямо з мобільного клієнта не можна (потрібен верифікований бізнес-аккаунт на стороні сервера). Це часто дивує команди, які хочуть «легку» інтеграцію.
Процес впровадження
Спочатку — аудит сценаріїв: які команди, потрібні ліде кнопки/каруселі, є ліле файловий обмін, потрібна ліле оплата (Telegram Payments vs WhatsApp Pay). Це визначає складність адаптерів.
Далі: проектування FSM, реалізація адаптерів послідовно (Telegram першим — найзрілішим API), інтеграція з основною логікою, навантажувальне тестування вебхуків.
Окремий етап — моніторинг: логування вхідних payload з маскуванням персональних даних, алерти на delivery_failed у Viber та невдалі верифікації вебхуків.
Часові орієнтири
Бот в одному мессенджері з базовими командами — 3–5 днів. Мультиканальна реалізація з FSM, файлами, кнопками та серверною частиною — 2–4 тижні. Якщо потрібна інтеграція з CRM або платіжними системами — окрема оцінка після аналізу вимог.







