Разработка · 7 мин чтения

Бот для рассылки в Telegram с кнопками: разбор функционала

За последние пару лет я делал несколько проектов, где клиенту нужен был именно бот для рассылки в Telegram с кнопками - не просто отправка текста по базе подписчиков, а сообщение с интерактивными действиями: подтвердить заказ, оставить отзыв, перейти в каталог, отследить доставку. Разберу, из каких частей состоит такой бот, как устроена логика кнопок и что обычно ломается у тех, кто собирает это своими силами на конструкторах.

Зачем в рассылке кнопки, а не просто текст

Обычная рассылка через Telegram Bot API - это push-сообщение, на которое пользователь может только прочитать и закрыть. С кнопками сообщение превращается в мини-интерфейс: пользователь жмёт «Записаться», «Узнать статус заказа» или «Отписаться от рассылки» прямо в чате, без перехода на сайт.

На практике это поднимает CTR рассылки в 2-3 раза по сравнению с рассылкой, где ссылка просто вставлена в текст. Причина простая: кнопка визуально выделена, занимает весь ряд под сообщением и не требует копировать ссылку в браузер вручную. Для интернет-магазина с ботом на базе aiogram, который уведомлял о статусе заказа, кнопка «Отследить в СДЭК» вела прямиком на трек-номер - конверсия в открытие трекинга выросла с 40% (когда ссылка была в тексте) до 78% после того, как она стала кнопкой.

Второй момент - аналитика. Каждое нажатие кнопки в Telegram генерирует callback-запрос с уникальным идентификатором, который бот может залогировать. То есть вы получаете точную статистику по кликам без сторонних трекеров, что для email или SMS-рассылок пришлось бы собирать через UTM-метки.

Инлайн-кнопки и reply-кнопки: в чём разница на практике

В Telegram Bot API два типа кнопок, и путать их - частая ошибка у новичков.

Inline-кнопки (InlineKeyboardMarkup) крепятся к конкретному сообщению и не занимают место в поле ввода. Нажатие отправляет боту callback_query, а сообщение можно потом отредактировать на месте - например, заменить кнопку «Подтвердить» на текст «Заказ подтверждён ✅». Это стандарт для рассылок: пользователь видит одно сообщение с одной или несколькими кнопками под ним.

Reply-кнопки (ReplyKeyboardMarkup) заменяют клавиатуру пользователя - по сути, это шаблоны текстовых ответов вроде «Да» / «Нет», которые бот получает как обычное текстовое сообщение. Для массовой рассылки они не годятся: клавиатура привязана к чату целиком, а не к конкретному сообщению, и через 5-10 новых сообщений от бота потеряется визуальная связь между кнопкой и тем постом, к которому она относилась.

Вывод простой: для рассылок почти всегда нужны inline-кнопки. Reply-клавиатуры оставляю для сценариев меню внутри диалога - регистрация, выбор категории в каталоге, ответы в опросе.

Из чего состоит бот для рассылки в Telegram с кнопками

Если собирать бота на Python (обычно беру aiogram 3.x или python-telegram-bot), архитектура держится на четырёх блоках:

  • Хранилище подписчиков - таблица в PostgreSQL или SQLite с chat_id, статусом подписки, тегами для сегментации;
  • Модуль формирования клавиатуры - генерирует InlineKeyboardMarkup под конкретную рассылку, с callback_data вида order_confirm:12345;
  • Очередь отправки - цикл с задержкой между сообщениями, чтобы не упереться в лимиты Telegram;
  • Обработчик callback_query - реагирует на нажатия, обновляет статус в базе и редактирует исходное сообщение.

Для небольших рассылок (до пары тысяч подписчиков) это укладывается в один файл на 150-200 строк. Для сегментированных рассылок с админкой, где менеджер выбирает аудиторию и текст через веб-интерфейс, добавляется отдельный backend и панель - тогда объём кода вырастает в разы, и я обычно оцениваю такой проект отдельно от базового бота.

Бесплатный материал

🎁 Полезный скрипт в подарок

Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.

Без спама. Отписка в 1 клик.

Пример: рассылка с кнопками на aiogram

Вот минимальный рабочий пример рассылки с двумя инлайн-кнопками и обработкой нажатия:

from aiogram import Bot, Dispatcher, F
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery
import asyncio

bot = Bot(token="YOUR_TOKEN")
dp = Dispatcher()

async def send_broadcast(chat_ids: list[int], text: str):
    kb = InlineKeyboardMarkup(inline_keyboard=[[
        InlineKeyboardButton(text="✅ Подтвердить", callback_data="confirm"),
        InlineKeyboardButton(text="❌ Отмена", callback_data="cancel"),
    ]])
    for chat_id in chat_ids:
        try:
            await bot.send_message(chat_id, text, reply_markup=kb)
        except Exception as e:
            print(f"Не отправлено {chat_id}: {e}")
        await asyncio.sleep(0.05)  # не более 20-30 сообщений в секунду

@dp.callback_query(F.data == "confirm")
async def on_confirm(callback: CallbackQuery):
    await callback.message.edit_text("Заказ подтверждён ✅")
    await callback.answer()

Обратите внимание на asyncio.sleep(0.05) - без задержки между отправками Telegram начинает возвращать ошибку 429 Too Many Requests уже после нескольких десятков сообщений подряд. Готовый скрипт с очередью отправки, ретраями и логированием ошибок я выкладывал в библиотеке готовых скриптов - там же есть версия с сохранением статуса рассылки в базу.

Сегментация базы и персонализация рассылки

Рассылка «всем подряд» работает первые пару раз, потом отписки растут. На реальных проектах сегментация обычно строится по трём осям:

  • Активность - когда пользователь последний раз писал боту (за 30 дней, за 90 дней, «мёртвые» контакты);
  • Действие в кнопке - кто нажал «Интересно», а кто «Не сейчас» в прошлой рассылке;
  • Источник - из какого канала пришёл подписчик (реклама, органика, партнёрская ссылка).

Технически это просто дополнительные поля в таблице подписчиков и WHERE-условие перед формированием списка chat_id для отправки. Сложность не в коде, а в том, что теги нужно проставлять на каждом шаге диалога - если это не продумать на старте, потом придётся переразмечать всю базу вручную.

Для интеграции с CRM (Bitrix24, amoCRM) обычно добавляю вебхук: когда клиент подтверждает заказ кнопкой в боте, статус летит в CRM автоматически, без ручного переноса. Это тот же принцип, что применяется при интеграции Tilda с оплатой через Т‑Банк или доставкой через СДЭК - событие в одной системе триггерит действие в другой.

Лимиты Telegram API и типичные ошибки

Telegram ограничивает ботов примерно 30 сообщениями в секунду в общем потоке и не больше 1 сообщения в секунду в один конкретный чат. При рассылке на 10 000+ подписчиков это значит, что процесс растягивается на 5-7 минут минимум, и это нормально - пытаться ускорить его костылями обычно приводит к временной блокировке бота на 429‑й ошибке.

Частые ошибки, с которыми сталкивался у клиентов, которые собирали бота сами или через фрилансера-новичка:

  • Отправка без try/except - один заблокировавший бота пользователь (тот, кто нажал «Остановить бота») обрывает всю рассылку на середине списка;
  • callback_data длиннее 64 байт - Telegram Bot API его просто не примет, кнопка не сработает;
  • Отсутствие callback.answer() - пользователь видит «часики» на кнопке до 10-15 секунд, хотя действие уже выполнено;
  • Хранение состояния рассылки в памяти процесса - при перезапуске бота (а он рано или поздно упадёт или обновится) прогресс рассылки теряется.

Сколько стоит и что выбрать: конструктор или кастомный бот

Здесь развилка: собрать рассылку в no-code инструменте типа n8n с нодой Telegram, или написать бота с нуля на aiogram. Сравнение по практике:

Критерий n8n + Telegram-нода Кастомный бот на aiogram
Сложность логики кнопок Простые сценарии без ветвления по callback Любая логика, включая многошаговые диалоги
Сегментация базы Ограничена возможностями подключённой БД-ноды Полный контроль через SQL-запросы
Интеграция с CRM/оплатой Через готовые ноды, если есть нужный коннектор Любой API, включая нестандартные
Скорость запуска 1-3 дня на типовой сценарий От 5-7 дней на MVP
Ориентир цены от 25 000 ₽ за настройку в n8n от 30 000 ₽ за бота на aiogram

n8n закрывает 80% сценариев рассылки с кнопками, если логика простая: разослать сообщение, собрать нажатия в таблицу, отправить уведомление менеджеру. Как только появляется сегментация по пятому признаку, персонализированный текст под каждого подписчика или интеграция с самописной CRM - n8n начинает упираться в лимиты нод, и дешевле сразу писать кастомный код.

Если смотреть на рынок в целом, у студий и на бирже фриланса за бота с рассылкой и кнопками просят обычно от 40 000 до 150 000 ₽ - разброс огромный из-за того, что под одним названием скрывается и простой скрипт на 100 строк, и полноценная админка с ролями. У себя веду фиксированную нижнюю границу и оцениваю каждый проект по объёму - какие интеграции нужны, сколько сценариев кнопок, нужна ли админ-панель для запуска рассылок без разработчика.

Разработку Telegram-бота обычно начинаю с короткого созвона, где уточняю сценарии кнопок и объём базы - это определяет, уложимся ли в базовую стоимость или нужна доработка.

Автоматизация в мессенджере

Telegram-бот / Mini App

от 30 000 ₽

Подробнее →

Частые вопросы

Сколько подписчиков может обработать один бот для рассылки в Telegram с кнопками?

Ограничений на размер базы у самого Telegram Bot API нет - упор идёт в скорость отправки, а не в лимит подписчиков. При грамотной очереди с задержками между сообщениями бот спокойно рассылает и на 50 000 контактов, просто сама рассылка займёт около 30-40 минут вместо пары минут.

Можно ли добавить кнопки в рассылку без написания бота, например через Tilda или готовый сервис?

Через сторонние сервисы массовой рассылки (типа коммерческих Telegram-рассыльщиков) - да, но там кнопки обычно ограничены типовыми шаблонами без кастомной логики на callback. Если нужна реакция на нажатие - записать статус, показать другое сообщение, дёрнуть вебхук в CRM - без бота с собственным обработчиком callback_query не обойтись.

Что будет, если пользователь заблокирует бота, а рассылка идёт по всей базе?

Bot API вернёт ошибку 403 Forbidden для этого конкретного chat_id. Если в коде нет обработки исключения, скрипт рассылки остановится на этом контакте и не дойдёт до остальных - поэтому try/except вокруг каждой отправки обязателен, а не опционален.

Кнопки в рассылке снижают процент попадания в спам или блокировку от Telegram?

Напрямую нет - блокировки связаны с частотой отправки и жалобами пользователей, а не с наличием кнопок. Но кнопка «Отписаться от рассылки», которая реально отписывает через отдельный флаг в базе, снижает число жалоб через встроенный репорт в Telegram, а массовые жалобы - один из факторов, из-за которых аккаунт бота может попасть под ограничения.

Есть задача?

Обсудим в мессенджере

Расскажите, что нужно сделать — отвечу в течение 4 часов в рабочее время. Первая консультация бесплатно.

Самозанятый Калинкин Н. А. · работаю с физлицами и юрлицами

Продолжая пользование настоящим сайтом Вы выражаете своё согласие на обработку Ваших персональных данных (файлов куки) с использованием Yandex.Metrika.
Понятно