Тур-агентство в мессенджере — отличная история: клиент задаёт 3–5 параметров, бот отдаёт топ-10 туров за 30 секунд, сравнивает, бронирует, присылает документы, поддерживает в поездке, напоминает о трансфере. Без бота тот же диалог занимает 40 минут в переписке менеджера + час обзвона по поставщикам. В этой статье — как спроектировать бот для тур-агентства в MAX: подбор по фильтрам, интеграция с GDS и агрегаторами (Sletat, TourVisor, Onlinetours API), бронирование, документы, push в поездке, допродажи (страховка, экскурсии, трансфер).
Что должен уметь бот тур-агентства
- Подбор тура: страна, даты, гости, бюджет, отель N* и выше.
- Сравнение 2–3 туров рядом (фото, цена, отель).
- Бронирование с предоплатой / полной оплатой.
- Загрузка паспортных данных туристов (с защитой ПДн).
- Документы: ваучер, авиабилеты, страховка — PDF присылаются в чат.
- Поддержка в поездке: «потерял документы», «как добраться», «отмена рейса».
- Допродажи: трансфер, экскурсии, ускоренный паспортный контроль.
- После возвращения — отзыв и предложение следующего тура.
Подбор тура
@bot.message_handler(commands=["search"])
async def on_search(msg):
await set_state(msg.from_user.id, "search:country")
kb = InlineKeyboardMarkup([
[InlineKeyboardButton("🇹🇷 Турция", callback_data="ctry:TR"),
InlineKeyboardButton("🇪🇬 Египет", callback_data="ctry:EG")],
[InlineKeyboardButton("🇦🇪 ОАЭ", callback_data="ctry:AE"),
InlineKeyboardButton("🇹🇭 Таиланд", callback_data="ctry:TH")],
[InlineKeyboardButton("Другая страна", callback_data="ctry:other")],
])
await bot.send_message(msg.chat.id, "Куда летим?", reply_markup=kb)
# дальше FSM: даты → гости → бюджет → отель
Состояние FSM в Redis:
state = {
"country": "TR",
"date_from": "2026-06-15",
"nights": 7,
"adults": 2,
"children": [10],
"budget_max": 250_000,
"hotel_min_stars": 4,
"meal": "all_inclusive",
}
Интеграция с поставщиками
Реальные источники в РФ-сегменте 2026 года:
| Источник | Что даёт | Особенности |
|---|---|---|
| Sletat.ru API | поиск туров от 100+ туроператоров | де-факто стандарт агентств |
| TourVisor API | альтернатива Sletat | более свежий API |
| Onlinetours.ru | каталог туров | подходит для лидогенерации |
| Прямые API туроператоров (TUI, ANEX, Pegas) | глубокая интеграция, лучше цена | сложнее в подключении |
Запрос к Sletat (упрощённо):
async def search_sletat(state: dict) -> list[dict]:
params = {
"departureId": 1, # Москва
"countryId": SLETAT_COUNTRY[state["country"]],
"dateFrom": state["date_from"],
"dateTo": add_days(state["date_from"], 3),
"nightsFrom": state["nights"] - 1,
"nightsTo": state["nights"] + 1,
"adults": state["adults"],
"kids": ",".join(str(a) for a in state["children"]),
"priceMax": state["budget_max"],
"starsMin": state["hotel_min_stars"],
"meal": state["meal"],
}
async with httpx.AsyncClient(timeout=30) as client:
r = await client.get(
"https://module.sletat.ru/Main.svc/GetTours",
params=params,
headers={"Authorization": f"Bearer {SLETAT_TOKEN}"},
)
return r.json()["tours"][:10]
Кеширование на 30 минут — обязательно: одинаковые запросы у разных пользователей дают тот же результат, экономите квоту API.
Карточка тура и сравнение
async def show_tour(chat_id: int, tour: dict):
text = (
f"*{tour['hotel']}* {'⭐' * tour['stars']}\n"
f"📍 {tour['region']}, {tour['country']}\n"
f"🛬 {tour['date_from']} → 🛫 {tour['date_to']} ({tour['nights']} ночей)\n"
f"🍽 {tour['meal']}\n"
f"👥 {tour['adults']} взр + {len(tour['kids'])} детей\n\n"
f"💰 *{tour['price']:,} ₽*\n\n"
f"_{tour['description'][:300]}..._"
)
kb = InlineKeyboardMarkup([
[InlineKeyboardButton("📋 Подробнее", callback_data=f"tour:full:{tour['id']}"),
InlineKeyboardButton("🆚 Сравнить", callback_data=f"tour:compare:{tour['id']}")],
[InlineKeyboardButton("✅ Забронировать", callback_data=f"tour:book:{tour['id']}")],
])
await bot.send_photo(chat_id, photo=tour["hotel_photo"], caption=text, reply_markup=kb, parse_mode="Markdown")
«Сравнить» — добавляет тур в сравнительный список (макс. 3), отдельная команда /compare рисует таблицу.
Бронирование и сбор паспортных данных
Это самый деликатный момент: ФИО, паспорт, дата рождения, гражданство — критичные ПДн. Шаги:
- Запрашиваем согласие на обработку ПДн (см. статью «Согласие и оферта в боте MAX»).
- Формы paspport — желательно через mini app с HTTPS, маскированием в чате, не plaintext в сообщении.
- На бэкенде шифруем перед сохранением (PostgreSQL
pgcryptoили приложением на AES-256). - Логи запросов в LLM/CRM — без ПДн (маскирование).
- Право на удаление (
/delete_my_data) — обязательно по 152-ФЗ.
@bot.message_handler(commands=["book"])
async def on_book(msg):
if not await has_consent(msg.from_user.id):
return await request_consent(msg)
# Открываем mini app для ввода паспортных данных
url = f"https://passport.tour-agency.ru/?token={await issue_form_token(msg.from_user.id)}"
kb = InlineKeyboardMarkup([[InlineKeyboardButton("Заполнить данные туристов", web_app=WebAppInfo(url=url))]])
await bot.send_message(msg.chat.id, "Заполните данные туристов в защищённой форме:", reply_markup=kb)
Оплата
Тур-агентство обычно работает с предоплатой 50% + остаток за 30 дней до вылета. Платежи — ЮKassa / Тинькофф Эквайринг с поддержкой рассрочки (Долями, Тинькофф Pay).
async def create_tour_payment(booking_id: int) -> str:
booking = await db.fetch_one("SELECT * FROM bookings WHERE id = $1", booking_id)
return await yookassa.create_payment({
"amount": {"value": str(booking.prepayment), "currency": "RUB"},
"confirmation": {"type": "redirect", "return_url": "https://t.me/tour_agency_bot"},
"description": f"Бронирование тура #{booking.id}",
"metadata": {"booking_id": booking.id, "user_id": booking.user_id},
"capture": True,
})
Документы как PDF
После подтверждения от туроператора — генерация и отправка PDF:
async def send_tour_documents(user_id: int, booking: Booking):
pdf_bytes = await render_pdf("ваучер", booking) # weasyprint / reportlab
await bot.send_document(user_id, document=pdf_bytes, filename=f"voucher_{booking.id}.pdf")
await bot.send_document(user_id, document=booking.tickets_pdf, filename="avia_tickets.pdf")
await bot.send_document(user_id, document=booking.insurance_pdf, filename="страховка.pdf")
await bot.send_message(user_id, "📁 Документы сохранены. Распечатайте перед поездкой.")
Поддержка в поездке
В день вылета — push «До трансфера 4 часа, паспорт и ваучер при себе». В аэропорту — «У вашего рейса задержка X часов» (через парсинг авиа API). На отдыхе — кнопка «🆘 Помощь» с прямым звонком в поддержку и быстрыми ответами на ТОП-вопросы:
- «Потерял паспорт» — инструкция + телефон консульства.
- «Болезнь, нужна страховая» — телефон страховой ассистанс.
- «Отмена обратного рейса» — что делать.
@bot.callback_query_handler(lambda c: c.data == "support:lost_passport")
async def on_lost_passport(call):
booking = await get_active_booking(call.from_user.id)
text = (
f"📞 Консульство РФ в {booking.country}: {EMBASSY_PHONE[booking.country]}\n"
f"📞 Наша поддержка 24/7: +7 (495) 000-00-00\n\n"
"1. Напишите заявление в полицию.\n"
"2. Получите справку.\n"
"3. С ней — в консульство за свидетельством на возвращение."
)
await bot.send_message(call.message.chat.id, text)
Допродажи (upsell)
Высокомаржинальные продукты:
- страховка от невыезда (5–7% от стоимости тура);
- расширенная медицинская страховка;
- индивидуальный трансфер вместо группового;
- экскурсии (партнёрка с локальными гидами);
- ускоренный паспортный контроль (Fast Track);
- повышение класса перелёта.
После бронирования — серия cross-sell сообщений с TTL 1 неделю до вылета:
async def cross_sell_cron():
bookings = await db.fetch_all("""
SELECT * FROM bookings
WHERE status='confirmed'
AND start_date BETWEEN now() + interval '5 days' AND now() + interval '14 days'
AND NOT cross_sell_sent
""")
for b in bookings:
await suggest_insurance(b)
await suggest_excursions(b)
await mark_cross_sell_sent(b.id)
Возврат и отмена
Сложный процесс. Бот автоматизирует первый шаг:
- запрос причины (передумали / болезнь / форс-мажор);
- расчёт штрафа по правилам туроператора;
- создание заявки в CRM на менеджера;
- отслеживание статуса возврата.
Финальное решение — за менеджером, бот просто стандартизирует и ускоряет.
Маркетинг и реактивация
После возвращения:
- отзыв (через
/feedback); - через 1 месяц — «Вы были в Турции в июне, может ОАЭ зимой?»;
- сегментация по бюджету / типу отдыха / детям.
CDP с историей путешествий + RFM-сегментация даёт CTR в 3–5 раз выше массовой рассылки.
152-ФЗ для тур-агентства
Особенно строго:
- ФИО, паспорт, дата рождения — это спецкатегория (биометрия для авиабилетов).
- Согласие на обработку с указанием цели.
- Согласие на трансграничную передачу — для туров за рубеж паспортные данные передаются туроператору, а оттуда — авиакомпании, отелю. Всё фиксируется.
- Право на удаление — после возврата клиент может попросить удалить ПДн, кроме обязательных к хранению (бухгалтерские документы — 5 лет).
Common pitfalls
- Кеш поиска с TTL 24 часа — цены меняются за минуты, продаёте «вчерашний» тур.
- Паспорт в plain text в чате — катастрофа по 152-ФЗ.
- Один менеджер на 1000 клиентов — поддержка валится в пик сезона.
- Нет напоминаний о трансфере — клиент опоздал в аэропорт, виноват кто? (Виноваты вы.)
- Без mini app для паспортов — клиенты пишут «Иванов 4509 123456» в открытом сообщении.
Итого
Бот для тур-агентства в MAX автоматизирует подбор по 5–8 параметрам, интегрируется с Sletat/TourVisor/Onlinetours, бронирует с предоплатой через ЮKassa, собирает паспортные данные через защищённую mini app с шифрованием, присылает PDF-документы, поддерживает в поездке push'ами и быстрыми сценариями, делает upsell страховки и экскурсий. Ключевые риски — 152-ФЗ (паспорта — спецкатегория ПДн), актуальность цен (кеш ≤ 30 минут), готовность поддержки в высокий сезон. MVP — 6–8 недель и 1–2 млн ₽; полнофункциональная версия с upsell, реактивацией, mini app для паспортов и интеграцией 3+ поставщиков — 12–18 недель и 3–6 млн ₽. Окупаемость — 4–8 месяцев за счёт снижения нагрузки на менеджеров и роста допродаж.
Частые вопросы
К каким API подключаться для подбора туров?
В РФ-сегменте 2026 года основной — Sletat.ru (де-факто стандарт, охватывает 100+ туроператоров), плюс альтернативы TourVisor и Onlinetours. Для глубокой интеграции и лучших комиссий — прямые API туроператоров (TUI, ANEX, Pegas, Coral), но это сложнее в подключении и поддержке. Обычно делают связку: Sletat для основного поиска + 1–2 прямых API крупнейших партнёров для эксклюзивных условий. Кешируйте результаты на 15–30 минут — экономит квоту и ускоряет ответы.
Как собирать паспортные данные в боте безопасно?
Категорически не в plain text в чат — это нарушение 152-ФЗ и риск утечки. Используйте mini app в MAX (или защищённую веб-форму) с авторизацией по одноразовому токену из бота. Поля валидируйте на клиенте и сервере. На бэкенде шифруйте поля паспорта/даты рождения через pgcrypto или приложением AES-256, ключ — в Vault. В чате никогда не цитируйте обратно полные паспортные данные, только last 4 цифры. Логи без PII. После завершения тура — оставляйте только обязательное по бухучёту.
Как часто обновлять цены и доступность?
Цены и места меняются в реальном времени — туроператоры закрывают категории за минуты. Кеш поиска — максимум 15–30 минут. На карточке тура перед бронированием обязательно делайте свежий запрос «availability check» в API поставщика. Если цена изменилась более чем на 5% — показываете «Цена изменилась с X на Y, продолжить?». Это защищает от продажи устаревших цен и от негативных отзывов «вы обещали 95 000, а в итоге 110 000».
Что бот должен делать в поездке клиента?
За 24 часа до вылета — напоминание про сборы, документы, время трансфера. За 4 часа — push «выезжайте через час». В аэропорту — мониторинг рейса через авиа-API (Aviasales, FlightStats), уведомление о задержках. В отеле — приветствие с контактами поддержки и скрипт «помощь по типовым ситуациям». За 24 часа до обратного рейса — напоминание о выезде. После возвращения — благодарность и просьба об отзыве. Это превращает бота из «сдал и забыл» в реальный сервис, что повышает повторные продажи на 30–50%.
Какие допродажи лучше всего работают?
Топ-3 по марже: страховка от невыезда (5–7% стоимости тура, конверсия 15–25% при предложении в правильный момент), индивидуальный трансфер вместо группового (+3–8 тыс. ₽, конверсия 20–30%), экскурсии (партнёрка с гидами, маржа 20–40%). Менее заметны, но прибыльны: расширенная медстраховка для пожилых и детей, повышение класса перелёта, ранний заезд / поздний выезд в отеле, упаковка багажа в аэропорту. Серия cross-sell сообщений с TTL 1 неделя до вылета — обычно 3–5 точек контакта.
Как обработать возврат и отмену тура?
Бот автоматизирует первый шаг: запрашивает причину (передумали / болезнь / форс-мажор), показывает расчёт штрафа по правилам туроператора (доступен через тот же Sletat API), создаёт заявку в CRM (amoCRM/Bitrix24) на менеджера. Финальное решение — за человеком: страховые случаи требуют документов, форс-мажоры — индивидуальной оценки. Бот трекает статус заявки и шлёт пользователю обновления, не заставляя его звонить и спрашивать. Среднее время разрешения сокращается с 5–7 дней до 1–2.
Сколько стоит и сколько занимает разработка?
MVP с подбором туров через 1 поставщика, бронированием, оплатой, выдачей документов — 6–8 недель и 1–2 млн ₽. Полнофункциональная версия с интеграцией 3+ поставщиков, mini app для паспортов, поддержкой в поездке, допродажами, реактивационными цепочками, кабинетом менеджера — 12–18 недель и 3–6 млн ₽. Поддержка инфраструктуры — 15–40 тыс. ₽/мес. Окупаемость для агентства с 100+ заявками в месяц — 4–8 месяцев за счёт снижения нагрузки на менеджеров (один обрабатывает 3× больше заявок) и роста среднего чека через upsell.