За последние пару лет я делал несколько проектов, где клиенту нужен был именно бот для рассылки в 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, а массовые жалобы - один из факторов, из-за которых аккаунт бота может попасть под ограничения.