Назад к статьям

Рассылки в телеграм боте: сегменты и статистика

В статье разберём рассылки в Telegram-боте: как отправлять по сегментам, добавлять кнопки и формы, собирать ответы и считать базовую статистику. Примеры на aiogram. Ограничения по отправке: Broadcasting (Telegram FAQ).

Сегментация базы

Подписчиков делят по тегам, по действиям (что нажимали, что покупали) или по дате подписки. Примеры сегментов: «все, кто за месяц нажал „Цены“», «все с тегом VIP». Рассылка уходит только выбранному сегменту — так вы не спамите тех, кому сообщение не подходит.

Пример функции рассылки по тегу. db.get_user_ids_by_tag(tag) — ваш запрос к БД (таблица пользователей с полем tag или отдельная таблица тегов). asyncio.sleep(0.05) снижает риск упереться в лимиты Telegram (порядка 30 сообщений в секунду в один чат). Исключения при send_message часто означают, что пользователь заблокировал бота — их можно логировать или считать.

import asyncio from aiogram import Bot from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton async def send_broadcast(bot: Bot, tag: str, text: str, button_url: str = None): user_ids = db.get_user_ids_by_tag(tag) # SELECT user_id FROM user_tags WHERE tag = $1 kb = None if button_url: kb = InlineKeyboardMarkup(inline_keyboard=[ [InlineKeyboardButton(text="Перейти", url=button_url)] ]) sent, failed = 0, 0 for user_id in user_ids: try: await bot.send_message(user_id, text, reply_markup=kb) sent += 1 await asyncio.sleep(0.05) # лимит Telegram ~30 msg/s except Exception: failed += 1 return sent, failed # для статистики

Кнопки и формы в рассылке

В сообщение можно добавить inline-кнопки: ссылка на сайт, переход в бота по deep link, запрос обратного звонка. Формы: например «Оставьте email» — по нажатию кнопки бот переводит в состояние FSM и сохраняет введённый email в БД или CRM.

Пример: рассылаем сообщение с кнопкой «Оставить email»; по нажатию включается состояние Form.email, следующий текст пользователя сохраняется. Нужны импорты: from aiogram.fsm.context import FSMContext и from aiogram.fsm.state import State, StatesGroup; класс Form(StatesGroup): email = State().

# Рассылаем сообщение с кнопкой «Оставить email» await bot.send_message( chat_id, "Акция! Оставьте email для уведомлений:", reply_markup=InlineKeyboardMarkup(inline_keyboard=[ [InlineKeyboardButton(text="Оставить email", callback_data="collect_email")] ]), ) @dp.callback_query(F.data == "collect_email") async def ask_email(callback: types.CallbackQuery, state: FSMContext): await state.set_state(Form.email) await callback.message.answer("Введите ваш email:") await callback.answer() @dp.message(Form.email, F.text) async def save_email(message: types.Message, state: FSMContext): if "@" in message.text: db.save_lead(message.from_user.id, message.text) # или отправить в CRM await message.answer("Спасибо! Мы пришлём уведомление.") await state.clear()

Статистика открытий

Полезно считать: сколько сообщений доставлено, сколько пользователей заблокировали бота (ошибка при отправке), сколько перешли по ссылке. Переходы по кнопке можно учитывать через короткие ссылки с параметром (например bit.ly или свой редирект с логированием) или через отдельного бота/сервис. В Telegram нет встроенной «статистики открытий» для произвольных сообщений; для каналов есть счётчик просмотров поста.

Минимальный учёт по рассылке: перед рассылкой сохраняете campaign_id, user_id, sent_at; при ошибке отправки — помечаете как failed. По этим данным можно строить отчёт «доставлено / не доставлено».

Итоги

Рассылки в боте работают лучше, когда есть сегментация и кнопки. Статистика помогает доводить контент до целевой аудитории и не перегружать всех подряд.