Это — статья о том, как команда Media Ingestion компании Airbnb создала цифровые открытки для групповых путешествий. Открытки было решено задействовать в летнем выпуске платформы 2024 года. В проекте использовался новый алгоритм подбора материалов под различные туристические направления. Здесь же применялись возможности платформы по обработке изображений и локализованных текстов.
Готовясь к летнему выпуску Airbnb 2024 года, команда Media Ingestion взяла на себя интереснейшую задачу. Она заключалась в разработке надёжной системы для создания цифровых открыток. Это должны были быть открытки, выглядящие, как изделия ручной работы, и при этом отражающие особенности самых разных уголков мира. Отправка открытки — это прекрасный способ приглашать гостей в групповое путешествие, и, в то же время, держать в курсе происходящего семью и друзей. Система требовала нового подхода к сопоставлению открыток со всеми возможными местами проживания, которые гости бронируют на Airbnb. Эта система должна была очень быстро создавать открытки, причём — не только на всех наших клиентских платформах (iOS, Android, Web), но и в разных системах обмена сообщениями, которые находятся за пределами приложения Airbnb. И всё это должно было делаться без отступления от высоких стандартов графического дизайна компании.
Задачи
Локализованный текстовый макет. Открытки должны быть оформлены с соблюдением строгих требований дизайна. Это касается количества символов в строке, межстрочных интервалов и кернинга в каждом из используемых языков. Это — типографика, соответствующая принципам «pixel perfect», правила переноса строк, а так же — стилизация, особенная для разных языков.
Гибкость дизайна и продукта. Текстовый макет, цвет, шрифты, тени шрифтов и трансформации изображений должны быть гибкими, позволяя вносить изменения в продукт и дизайн.
Подбор открыток для разных пунктов назначения. Открытки должны соответствовать пунктам назначения. Это достигается путём включения в них подходящих рисунков и локализованных названий пунктов назначения.
Доступность как на платформе Airbnb, так и за её пределами. Открытки должны отображаться как на платформе Airbnb, так и за её пределами. Это означает необходимость их предварительного генерирования на сервере. Решение, предусматривающее формирование открыток исключительно на клиенте, нам не подошло бы. Дело в том, что нам, например, для корректного вывода открыток в iMessage и Instagram, нужны были ссылки на открытки, совместимые со стандартом Open Graph.
Производительность. Показ открытки не должен отнимать слишком много ресурсов и мешать работе с приложениями.
Решение задач
Как устроена открытка?
Наши открытки — это комбинация из (1) изображения, (2) шаблона открытки и (3) локализованного названия пункта назначения. «Шаблон» открытки — это объект данных, содержащий ссылку на изображение, а так же — некоторые дополнительные метаданные, описывающие особенности рендеринга открытки. Для того чтобы сформировать открытку в продакшне, нам, прежде чем пользователь сможет её увидеть, нужно обладать некоторыми материалами. Это — изображения, шаблоны открыток, отформатированные и локализованные названия пунктов назначения.
В следующем примере показано, что у нас имеется изображение склона утёса, шаблон открытки и название пункта назначения (Galway) на английском. Шаблон включает в себя параметры, определяющие порядок создания открытки. Это — цвет и положение текста и Belo (логотипа Airbnb). Здесь видно, что текст и Belo выводятся серым цветом и располагаются, соответственно, в нижней части открытки и в её верхнем левом углу.
Гибкость дизайна и шаблоны открыток
Для того чтобы обеспечить возможность применения изменяющихся требований к дизайну открыток, мы создали гибкую модель данных шаблона. Она позволяет дизайнерам настраивать в ходе работы различные параметры открыток, вроде позиционирования и цвета текста. Шаблоны включают в себя всё, что нужно для генерирования открыток и элементов, которые дополняют открытки. Наша модель данных, кроме того, поддерживает возможности по управлению версиями кода. Это позволяет публиковать общедоступные изменения, меняя и версию продукта. Смысл этих изменений может заключаться в изменении дизайна или в исправлении визуальных дефектов открыток.
Шаблоны и изображения: выгрузка, управление, предварительный просмотр
Для того чтобы творческой команде было легче работать, не прибегая к помощи других специалистов, и самостоятельно решать проблемы, мы создали внутренний инструмент, основанный на веб-технологиях. Он предназначен для создания шаблонов и для управления ими. Он обеспечивает предварительный просмотр открыток и выгрузку изображений на сервер. Этот инструмент значительно упростил задачи по управлению шаблонами. Особенно полезным он оказался в период, когда на команду ложилась максимальная нагрузка, когда она постоянно исправляла ошибки и меняла дизайн.
Локализованный текстовый макет
Нам требовались точные переводы названий пунктов назначения, которые должны были корректно отображаться на каждой из локализованных открыток. Программная система для создания локализованных текстовых макетов потребовала бы, как минимум, наличия правил, отражающих специфику различных языков (направление письма, переход на новую строку и прочее). Сюда же относится знание культурных традиций, принятие во внимание соображений доступности контента, учёт особенностей вывода специальных символов (диакритических знаков и прочего подобного). Всё это могло бы сделать логику работы такой системы сложной и подверженной ошибкам.
Мы, вместе с командой локализации, пришли к компромиссу относительно подобной системы. А именно — мы вручную отформатировали переводы для пунктов назначения, входящих в топ наших направлений бронирования. В процессе подготовки этих материалов нашей команде локализации понадобилось перевести и отформатировать (настроить переносы строк, расстояния между различными элементами макета и прочее) открытки для избранных пунктов назначения. Затем мы помогли им, используя некоторые средства автоматизации, перенести эти данные на нашу стандартную платформу, используемую для интернационализации проектов. После переноса данных система, генерирующая открытки, получает макеты для локализованного отформатированного текста с платформы интернационализации.
Список ведущих направлений бронирования был составлен нашей командой дата-сайентистов. Они помогли нам отобрать самые популярные пункты назначения по языкам. Это позволило уменьшить масштабы генерирования открыток. Так, без этого речь шла бы о создании открыток на всех языках для всех пунктов назначения. А после отбора нужно было создать открытки лишь для небольшого подмножества направлений. В результате значительно упростился контроль качества открыток. Но ещё важнее то, что это позволило не усложнять код системы и её поддержку. Нам не понадобилось тысяч строк кода, описывающих логику работы с языками!
Остальные открытки, не относящиеся к списку ведущих направлений, формировались с применением простых формул, описывающих, для каждого из языков, параметры, связанные с количеством слов на строку и с переносом слов на новую строку. Например — в китайском, корейском и японском языках лимит количества слов был меньше, чем в других случаях. Дело тут в размерах символов, а так же — в отсутствии переносов на новую строку и пробелов, так как они меняют смысл слов, обозначающих пункты назначения.
Генерирование открыток
Сопоставление макета и пункта назначения
Для подбора шаблона открытки, который наилучшим образом подходит для некоего пункта назначения, мы создали специальный алгоритм. Он подбирает шаблоны под арендуемое жильё в момент бронирования. Подбор осуществляется с использованием одного из четырёх подходов:
По конкретному объявлению. Нам нужна была поддержка изображений, привязанных к конкретным объявлениям о сдаче жилья. Например, в наших объявлениях из категории «Суперзвёзды» показывается золотой билет — в ознаменование того особого момента, когда гость выиграл в лотерею возможность остановиться в «звёздном» жилье.
По пункту назначения. Для популярных пунктов назначения (определяемых городом и страной) мы подготовили тщательно отобранные изображения, которые представляют и местных художников, и сами пункты назначения. Например — тот, кто путешествует в Санторини, увидит открытку с изображением знаменитых кикладских куполов Санторини (одну из таких открыток можно увидеть ниже).
По ключевым словам. В случае со всеми остальными изображениями, мы подбираем их, руководствуясь набором ключевых слов. Мы, работая совместно с командой, которая занимается графом знаний, назначили ключевые слова всем объявлениям. Эти ключевые слова описывают места по нескольким категориям: плотность населения (крупный город с пригородами, город), климат (тропический, умеренный), территориальная характеристики (прибрежный, горный, речной регион). Мы обеспечиваем точность классификации, сопоставляя существующую информацию из наших внутренних источников и информацию от региональных представительств. Был создан API, позволяющий получать ключевые слова для конкретного объявления. А, на стороне системы создания открыток, наша продакшн-команда классифицировала изображения, назначив им соответствующие ключевые слова. Например, некое изображение может классифицироваться следующим образом: оно подходит для создания открытки, связанной с пунктом назначения, который расположен в прибрежной зоне, имеет умеренный климат и является частью крупного города с пригородами. Мы, генерируя открытку, находим соответствующие друг другу объявление и изображение, ориентируясь на максимальное число совпадающих ключевых слов.
Выбор стандартного изображения, используемого по умолчанию. Если пункт назначения не попадает ни в одну из вышеперечисленных категорий — мы берём стандартное изображение, используемое по умолчанию.
Подготовленные текстовые материалы
Мы берём объявление из каждого запроса на бронирование жилья и извлекаем из него сведения о городе и стране. Далее — мы проверяем, есть ли этот пункт назначения в списке отобранных мест, материалы для которых подготовлены, отформатированы и загружены в сервис интернационализации. Затем мы подбираем изображение, которое лучше всего подходит для пункта назначения и внедряем в него локализованный текст, формируя готовую открытку. Если перевод найти не удаётся — мы используем резервный вариант и формируем открытку без текста.
Производительность и асинхронный конвейер создания открыток
Размещение локализованного названия пункта назначения и логотипа Airbnb на изображении — это, учитывая то, что мы используем изображения высокого разрешения, ресурсоёмкая операция. Мы выяснили, что процесс обработки изображения может занимать, в среднем, до 8 секунд. Поэтому нам нужно было найти способ ускорения получения ответов от API, генерирующего открытки. Мы, кроме того, хотели перемещать сгенерированные открытки в наше главное хранилище изображений. Это позволило бы использовать существующую инфраструктуру обработки медиаматериалов, что, однако, замедлило бы процесс создания открытки ещё на 1-2 секунды.
Для того чтобы решить все эти задачи, и при этом выйти на хороший уровень производительности, мы решили применить частично асинхронный подход. А именно, если при работе пользователя с системой поступает запрос на получение открытки, мы возвращаем лишь те открытки, которые мы уже сгенерировали и сохранили во внутреннем хранилище. Если же в ответ на запрос нужно вернуть новую открытку, мы, вместо этого, возвращаем стандартную открытку. Далее — мы публикуем событие в очередь Kafka. Там асинхронный потребитель вызывает сервис, формирующий открытки, ждёт создания открытки, а потом переносит её в систему для будущего использования.
На следующей схеме показано, как мы параллельно загружаем сведения об объявлении и о ключевых словах, делая это до нахождения изображения, которое наилучшим образом подходит для конкретного путешествия. Основываясь на паттерне хранения открыток, мы обращаемся к медиа-сервису, узнавая — есть ли в его распоряжении открытка, которая нам нужна. Делается это до того, как мы либо сможем возвратить созданную ранее открытку, либо, если открытку найти не удастся, запустим асинхронный процесс её создания. В этот момент потребитель Kafka преобразует переданные ему материалы в готовую открытку и сохранит её в системе.
Предварительное создание открыток
Нам, перед запуском нового функционала, хотелось сгенерировать как можно больше открыток. Если открытка не была сгенерирована до того момента, когда гость бронирует жильё для совместного путешествия, все участники группы получат стандартные, универсальные открытки. Наша команда дата-сайентистов помогла определить ведущие направления путешествий, а мы пропустили эти данные через конвейер генерирования открыток. Мы стремились заблаговременно создать как можно больше открыток и минимизировать шансы показа клиентам стандартной открытки. В течение недели после запуска более 90% путешествий снабжались собственными открытками, и мы, в последующие месяцы, постепенно приблизились к созданию уникальных открыток для всех путешествий.
Итоги
Создание открыток — это большой проект, потребовавший взаимодействия множества команд. Это — команды инженеров, дизайнеров, дата-сайентистов, продуктовые команды. Проект нацелен на улучшение впечатлений пользователей от групповых путешествий. Наша команда Frontline Insights продолжает получать позитивные отзывы из разных источников, касающиеся этого новшества, добавляющего людям приятных впечатлений в тот момент, когда они присоединяются к групповому путешествию.
То решение задачи, на которое мы вышли, подчёркивает важность применения правильных внутренних инструментов. Это касается использования подходящих систем для обработки текста и изображений, а так же — применения алгоритмов, позволяющих сопоставлять материалы, из которых создают открытки, с пунктами назначения. Любая мелочь может оказаться крайне важной, если речь идёт о реализации каких-либо проектов в масштабах такой компании, как Airbnb.
О, а приходите к нам работать? ? ?
Мы в wunderfund.io занимаемся высокочастотной алготорговлей с 2014 года. Высокочастотная торговля — это непрерывное соревнование лучших программистов и математиков всего мира. Присоединившись к нам, вы станете частью этой увлекательной схватки.
Мы предлагаем интересные и сложные задачи по анализу данных и low latency разработке для увлеченных исследователей и программистов. Гибкий график и никакой бюрократии, решения быстро принимаются и воплощаются в жизнь.
Сейчас мы ищем плюсовиков, питонистов, дата-инженеров и мл-рисерчеров.