Сообщения менеджера из CRM пропадали в никуда, хотя всё было настроено верно. Нашли, что их блокировал сам Битрикс
По API это выглядит прямолинейно. Покупатель пишет на Авито → мы кладём сообщение в чат-линию Битрикса через `imconnector` → оператор отвечает → Битрикс шлёт нам вебхук с ответом → мы отправляем его обратно покупателю на Авито. Собрали, подписали оба события, проверили на тестовом портале синтетическим покупателем — долетает, диалог открывается, ответ оператора уходит, всё по схеме.
На портале клиента та же цепочка встала колом. Менеджер отвечает в чат-линии — и видит красную пометку «Не доставлено». У нас в логах API, в логах прокси, даже в `tcpdump` на входящем порту — ничего. Не 403, не таймаут, а полная тишина: ни одного входящего соединения с портала клиента. При этом ровно тот же обработчик, та же подписка на событие с тестового портала продолжала исправно слать вебхуки.
Первая гипотеза — приложение просто не доустановлено. Проверили: `app.info` портала клиента отдавал `installed: false`, хотя страница установки открывалась и администратор вроде бы всё подтверждал. Оказалось, страница вызывала библиотеку Битрикса с чужого домена, который у части клиентов блокируется сетью — скрипт не загружался, кнопка «Готово» жала в пустоту, финальный вызов `installFinish` не происходил. Поставили на страницу свою копию библиотеки — `installed` стал `true`. Переподписали событие. Тест-пинг от Битрикса в ответ — снова тишина.
Вот тут стало интересно. Если приложение установлено и подписка подтверждена, а вебхук всё равно не приходит именно с этого портала — значит, дело не в установке и не в коде, а в самой доставке. Проверили руками: привязали тестовое событие на тот же путь, но с добавленным к адресу параметром версии — и пинг Битрикса долетел мгновенно, хоть и с ожидаемой ошибкой (наш обработчик не знал этот путь). Разница — только хвост URL.
Вывод: Битрикс у конкретного портала «залип» на точном адресе обработчика. Несколькими неделями раньше тот же адрес отвечал ошибкой на другое событие — побочный эффект отдельного бага в нашей обвязке авторизации, который мы к тому моменту уже починили. Но Битрикс, судя по всему, запоминает серию неуспешных ответов на конкретный URL и после этого просто не пытается доставить на него новые события — без предупреждения, без пометки в интерфейсе администратора, без строчки в документации API. С точки зрения разработчика выглядит так, будто подписка работает — `event.bind` возвращает успех, — а по факту канал глухой.
Лечится это не кодом, а переподпиской событий на новый вариант адреса. Переподписали оба события клиента на путь с версией — и тестовое сообщение от оператора в чат-линии долетело до покупателя на Авито за секунды, в Битриксе появилась галочка доставки вместо красной отметки. Отдельно погасили эхо: без этого бот на стороне Авито получал обратно то же сообщение, которое только что ушло от живого менеджера, и путал его с новым обращением.
Сейчас менеджер клиента отвечает покупателям на Авито прямо из Битрикса — с рабочего стола или с телефона, без второго приложения под рукой. Для нас это закрывает вопрос, который раньше решали руками: часть диалогов терялась именно на стыке двух систем, пока сообщение переключали из одного интерфейса в другой.
Если у вас где-то стоит похожая связка — свой вебхук, который принимает события от внешней платформы, — и интеграция внезапно замолкает, хотя настройки выглядят правильно: прежде чем чинить код, проверьте, не «запомнила» ли платформа серию неуспешных ответов на точный URL обработчика. Иногда единственное, что нужно поменять, — это сам адрес, а не логику за ним.