Вебхуки Авито — это подписка на события: вместо того чтобы каждые несколько секунд спрашивать площадку «не было ли новых сообщений», вы сообщаете ей адрес, и она сама присылает туда уведомление, как только покупатель написал. Задержка падает с десятков секунд до долей секунды, а расход лимитов запросов — до нуля в спокойное время.
Цена этого удобства — свой сервер с публичным HTTPS и дисциплина в обработке. Уведомление могут доставить дважды, могут доставить с задержкой, а во время вашего обеденного деплоя не доставить вовсе. Всё это надо предусмотреть заранее, иначе бот будет отвечать по два раза и терять диалоги.
Как это устроено в общих чертах
Схема одинакова почти во всех платформах. Вы регистрируете адрес, на который площадка будет слать уведомления. Когда происходит событие — например, новое сообщение в чате, — она отправляет на этот адрес запрос с описанием события. Ваш сервер должен быстро ответить успехом. Если он ответил ошибкой или не ответил вовремя, попытку повторяют.
Конкретные адреса регистрации, формат тела и состав полей смотрите в официальной документации Авито: они уточняются, и переписывать их по памяти было бы вредно. Что от версии не зависит — это принципы, о которых дальше. Общий контекст доступа к переписке разобран в статье про API мессенджера Авито.
Что должен делать обработчик
Правильный обработчик вебхука делает три вещи и ни одной лишней:
def on_event(request):
if not signature_ok(request): # проверка подлинности, если платформа её даёт
return 403
event_id = extract_id(request.body) # идентификатор события или сообщения
if already_seen(event_id): # защита от повторной доставки
return 200
enqueue(request.body) # положить в очередь и выйти
return 200
Обратите внимание: внутри нет ни обращения к языковой модели, ни отправки ответа покупателю. Это принципиально. Всё, что дольше пары сотен миллисекунд, делается в фоне. Если вы будете генерировать ответ прямо в обработчике, площадка не дождётся вашего успеха, посчитает доставку неудачной и пришлёт то же событие ещё раз — и вот у вас уже два ответа на одно сообщение.
Повторная доставка — это норма
Самое частое заблуждение новичка: «раз событие одно, придёт оно один раз». Нет. Гарантия у таких систем обычно звучит как «доставим хотя бы раз», а не «ровно раз». Причины повтора: ваш таймаут, ваш пятисотый ответ, сетевой сбой на середине, перезапуск вашего процесса в момент обработки.
Защита простая и обязательная: таблица обработанных событий. Идентификатор — первичный ключ, вставка с проверкой на конфликт. Пришло событие, которого нет в таблице, — обрабатываем. Пришло уже известное — молча отвечаем успехом.
Хранить эту таблицу вечно не нужно, достаточно нескольких суток. Но она должна переживать перезапуск: множество в оперативной памяти обнулится при первом же деплое, и весь утренний поток сообщений обработается заново.
Гонка при параллельных сообщениях
Второй подводный камень виден только на живом трафике. Покупатель пишет три сообщения подряд с интервалом в секунду. Площадка честно шлёт три вебхука. Ваш веб-сервер честно обрабатывает их параллельно в трёх потоках. Бот отправляет три ответа, причём в произвольном порядке — потому что генерация третьего закончилась раньше первого.
Что помогает:
- Блокировка по диалогу. Ключ блокировки — идентификатор чата. Одновременно обрабатывается один чат, остальные события ждут своей очереди.
- Окно склейки. После первого сообщения ждём две-три секунды: вдруг покупатель дописывает. Потом отвечаем на всё сразу, одной репликой.
- Проверка перед отправкой. Прямо перед отправкой ответа сверяемся, не появилось ли в чате новых сообщений от покупателя. Появились — пересобираем ответ.
Побочный эффект окна склейки приятный: ответ перестаёт быть мгновенным. Ответ через полсекунды выглядит машинным, ответ через несколько секунд — как живой человек, который быстро печатает. Про то, почему скорость всё равно решает, — в разборе как отвечать на Авито быстро.
Готовые сервисы разбираются с этим за вас: у «Папы БУ» склейка сообщений и защита от дублей уже внутри, настраивать их продавцу не нужно.
Чего вебхуки не заменяют
Подписка на события — не единственный источник правды. Ваш сервер иногда лежит: деплой, перезагрузка, сбой у хостера. За это время события ушли в никуда или повторы закончились.
Поэтому рабочая схема — гибридная. Вебхуки дают скорость в обычном режиме, а фоновая задача раз в несколько минут спрашивает у площадки список непрочитанных диалогов и подбирает то, что потерялось. Дубликаты при этом отсечёт та же таблица обработанных событий, что и раньше — она нужна одна на оба источника.
Что понадобится из инфраструктуры
- Домен и сертификат. Самоподписанный не подойдёт, нужен нормальный, обновляемый автоматически.
- Быстрый веб-сервер. Достаточно самого лёгкого фреймворка: логики в обработчике почти нет.
- Очередь. На старте годится таблица в базе с пометкой статуса. Отдельный брокер сообщений нужен, когда диалогов станут тысячи.
- Логи запросов. Сырое тело каждого входящего события, сохранённое на несколько дней, экономит недели догадок.
- Мониторинг молчания. Оповещение, если за час в рабочее время не пришло ни одного события. Тишина — тоже симптом.
Когда вебхуки не нужны
- Мало диалогов. При пяти сообщениях в день опрос раз в минуту решает задачу без сервера и сертификата.
- Негде разместить публичный адрес. Туннель с ноутбука — инструмент отладки, а не рабочая схема.
- Вы уже используете готовый сервис. Он подписывается на события сам, дублировать это своим кодом бессмысленно.
- Ночная нагрузка вас не волнует. Хотя обычно волнует: заметная часть обращений приходит вечером и ночью, об этом — в статье про ответы ночью на Авито.
Коротко
Вебхуки Авито дают скорость и экономят лимиты, но требуют своего сервера, обязательной защиты от повторной доставки и аккуратной работы с параллельными сообщениями в одном диалоге. Обработчик должен быть тупым и быстрым: проверил, положил в очередь, ответил успехом. Всё остальное — в фоне, плюс фоновый опрос как страховка на случай простоя.
Если хочется получить результат — ответ покупателю за минуту в любое время суток — не строя всю эту обвязку, посмотрите, как это работает в готовом виде.
Если решение под свой бизнес нужно, а разбираться самому некогда — напишите мне в Telegram: @artem_sergeevic. Я делаю такие сервисы на заказ: обсудим задачу и честно разберём, что в ней действительно нужно, а что можно не делать вовсе.