Все гайды

Интеграции без API: когда письмо становится контрактом

Что делать, когда у контрагента нет API: письмо как источник данных, адаптеры по каналам, идемпотентность и границы браузерной автоматизации.

TL;DR. Половина процессов в малом и среднем бизнесе завязана на контрагента, который интеграции не даёт: у площадки нет партнёрского API, у поставщика — только личный кабинет, у перевозчика — письма. Данные при этом всё равно приходят машиночитаемо — письмом. На нём можно построить надёжную интеграцию, если сразу заложить три вещи: адаптер на каждый канал, устойчивый идентификатор события и обработку отмен наравне с подтверждениями.

Когда API нет и не будет

Обычный сценарий: занятость, заказы или отгрузки ведутся сразу на нескольких площадках, каждая знает только про себя. Пока данные не сведены в одном месте, один и тот же слот, товар или машина уходят дважды.

Стандартный ответ — интеграция по API. Он упирается в то, что партнёрского API у части контрагентов просто нет: ни выгрузки событий, ни управления доступностью. Остаётся ручной обход личных кабинетов после каждого события — то есть работа, которую невозможно делать без пропусков.

Но машиночитаемый выход у такой площадки обычно всё-таки есть. Это письмо-уведомление, которое она присылает на каждое событие. Оно приходит в предсказуемый ящик, содержит все нужные поля и появляется в момент события, а не по расписанию опроса.

Письмо в такой схеме — не костыль, а осознанно выбранный источник данных. Разница принципиальная: костыль пишут наспех и не сопровождают, а источник данных проектируют.

Что заложить с самого начала

Адаптер на каждый канал. Формат у всех разный: одна площадка кладёт вложение в формате ICS, другая присылает HTML, где данные лежат в вёрстке шаблона, третья отличает отмену от подтверждения только темой письма. Общего парсера здесь быть не может. Зато при разделении по каналам смена шаблона у одной площадки ломает один адаптер, а не весь сбор — и это видно сразу, а не через неделю.

Устойчивый идентификатор события. Самая дорогая ошибка в такой интеграции — дубли. Письмо может прийти дважды, обработка может упасть на середине и повториться. Поэтому у каждого события должен быть ключ, который не меняется между попытками: идентификатор письма, UID из вложенного календарного файла или их комбинация. Идемпотентность здесь не украшение — без неё календарь заполняется призрачными записями, и доверие к системе теряется на первой же неделе.

Отметка на обработанном. Разобранное письмо помечается ярлыком прямо в почте. Это одновременно защита от повторной обработки и способ увидеть глазами, что система вообще видела, а что прошло мимо неё.

Отмены — полноценный сценарий, а не исключение. Пропущенное подтверждение заметят сразу. Пропущенную отмену не заметит никто: даты останутся закрытыми, слот не продастся, и потерю обнаружат в конце месяца по выручке. Обработка отмен закладывается в каждый адаптер с первого дня, а не добавляется потом.

Обратная запись: где заканчивается почта

Собрать данные в одном месте — половина задачи. Вторая половина — закрыть занятые даты или позиции в остальных каналах. Письмом это не сделать: письмо приходит от площадки, а не уходит к ней.

Здесь остаётся браузерная автоматизация — сценарий, который заходит в личный кабинет и выполняет действие руками пользователя. И вот тут важно разделить две части:

Развязка этих двух частей даёт полезное свойство: задания копятся в очереди независимо от того, готов ли сценарий для конкретного канала. Появился сценарий — накопленное выполняется без переделки логики. И статус готовности имеет смысл вести по каждому каналу отдельно: где-то работает полный цикл, где-то только приём событий. Сведение их в один общий статус «интеграция работает» — надёжный способ незаметно потерять часть данных.

Чего эта схема не даёт

Где ещё это применимо

Схема «письмо как источник данных → нормализация → единая база или календарь» переносится на любой процесс, где контрагент не даёт интеграции:

Признак задачи один и тот же: событие происходит у контрагента, приходит письмом, а дальше кто-то переносит его руками.

Как мы это делали

Если процесс завязан на контрагента, который не даёт интеграции, — обсудим за 30 минут.