Осенью прошлого года перед нами стояла задача объединить крупнейшую социальную сеть и многомиллионный сервис объявлений в одну площадку для продажи — Объявления ВКонтакте. Похожую задачу уже решил Facebook и реализовал  внутри своей соцсети Facebook Marketplace, в результате получился один из крупнейших мировых сервисов объявлений.  В этой статье я опишу процесс разработки и технологии, которые мы использовали для достижения результатов в максимально сжатые сроки. Не буду приводить примеры кода, потому что архитектура каждой части приложения заслуживает отдельной статьи. Юла — сервис объявлений с многомиллионной аудиторией, который является одним из крупнейших сервисов объявлений в РФ. ВКонтакте — крупнейшая социальная сеть РФ, которая также является одним из крупнейших сервисов объявлений: там есть множество сообществ-барахолок, в которых пользователи могут размещать объявления.  Полгода назад у пользователей ВКонтакте не было удобной функциональности поиска объявлений и взаимодействия с покупателями и продавцами, а на Юле не было того количества постов из групп ВКонтакте, которые являются потенциальными объявлениями. Большинство постов-объявлений во ВКонтакте выглядели так:  Кроме того, у сообществ ВКонтакте не было возможности получать дополнительную аудиторию и показывать свой контент вне ленты групп. ВКонтакте и Юлу объединяет то, что оба приложения находятся внутри холдинга VK, поэтому разумным шагом было направить сотрудничество обеих команд на создание объединенного сервиса. Естественно, разработка базовой функциональности Юлы на мобильных клиентах ВКонтакте — дело небыстрое. А нам, как обычно бывает, хотелось сделать MVP сервиса как можно скорее. К счастью, на базе ВКонтакте существует платформа миниаппов, которая позволяет встраивать их внутрь ВКонтакте. Именно её мы решили использовать для решения нашей амбициозной задачи. Сначала вкратце расскажу, что из себя представляет платформа миниаппов ВКонтакте.  Сам миниапп может быть встроен в сайт ВКонтакте (мобильную или десктопную версию) через iframe, а в приложение ВКонтакте на Android/iOS — через webview. На базе миниаппов уже созданы тысячи приложений. Это делает ВКонтакте супераппом. Любой разработчик может написать своё приложение, разместить заявку и попасть в список приложений. Внешние тестировщики проверяют приложения перед размещением в списке, что позволяет запускать их с минимальным количеством багов.  Команда разработки ВКонтакте создала библиотеку интерфейсов vkui. Она представляет из себя набор React-компонентов, с помощью которых можно быстро создавать веб-приложения с таким же стилем, как у ВКонтакте. Библиотека использует в качестве стилей цветовые токены на основе css-custom-properties. Это позволяет отображать корректные цвета в тёмной и светлой темах (тёмная тема в последнее время достаточно популярна). Также библиотека меняет стили компонентов в зависимости от платформы: Android/iOS/Web. Для взаимодействия с API ВКонтакте и мобильными клиентами используется прослойка vk-bridge. Например, можно отправить события получения ФИО пользователя, данных о текущей геолокации, версии официального приложения, и даже сохранить пользовательские данные в key/value-хранилище (vk-storage). Для получения некоторых пользовательских данных приложение ВКонтакте запрашивает у пользователя специальное разрешение. О самой библиотеке можно подробнее узнать тут. Сервис Юлы состоит из нескольких вертикалей, в каждой из которых пользователь может найти объявления определённой категории: Одна из вертикалей, над которой велась активная работа в прошлом году, это вертикаль услуг. Кроме её разработки внутри Юлы была поставлена задача обкатать технологию миниаппа, чтобы использовать внутри ВКонтакте вертикаль Юлы в виде миниаппа услуг. Это позволило разработчикам ознакомиться с технологиями и подготовить фундамент для создания Объявлений ВКонтакте. Параллельно разработке велись переговоры о более тесной интеграции с ВКонтакте и прорабатывались задачи. Сам миниапп услуг включал в себя основные экраны Юлы: ленту объявлений, карточку товара и экран создания объявления.  Одним из самых сложных этапов реализации миниаппа услуг была попытка внедрения оплаты. Работа над этой функциональностью заслуживает отдельной статьи, но я расскажу, в чём была основная сложность. Помимо миниаппа, фронтенд-команда Юлы занимается разработкой веб-сайта youla.ru. Мы пытались переиспользовать функциональность оплат из веб-Юлы, где это было реализовано через Деньги Mail.ru. Но из-за того, что весь процесс происходит внутри iframe, а ссылка на оплату формируется через redirect-url, возврат в миниапп после оплаты срабатывал некорректно. В итоге мы отказались от этой функциональности. В дальнейшем при внедрении оплаты в Объявления ВКонтакте мы использовали уже VK Pay взамен Деньги Mail.ru. В Юле есть два основных канала связи пользователей с друг другом: звонок по номеру телефона и переписка через чат. Если функциональность звонков реализовать несложно, то написать с нуля чаты, или даже перенести эту функциональность из другого проекта, — весьма нетривиальная задача. К счастью, у ВКонтакте есть мессенджер, в котором мы настроили интеграцию через собственного чат-бота. Он позволял дублировать сообщения в чатах Юлы и ВКонтакте, и покупатель мог внутри ВКонтакте переписываться с продавцом, который пользовался приложением или веб-сайтом Юлы. Для разработки веб-версии Юлы мы используем монорепозиторий, который собирается через Lerna. Он состоит из пакетов, отвечающих за бизнес-логику сайта, переиспользуемые UI-компоненты, утилиты, сервисы и дизайн-систему. Для работы со стилями мы используем Styled-components, с их помощью реализована наша дизайн-система. В качестве основы для приложения миниаппа услуг мы взяли React CreateApp, в котором в дальнейшем сделали eject, потому что нам не хватало базовой функциональности. Вся визуальная составляющая была реализована на vkui, что позволило довольно быстро реализовать экраны приложения. В них мы поменяли цвета, чтобы они соответствовали дизайн-системе Юлы, для этого подключили npm-пакет со стилями и использовали некоторые UI-компоненты. Вся разработка миниаппа услуг заняла два месяца и ещё один на отлаживание процесса развёртывания, релизов и мелкие доработки. Первым этапом разработки миниаппа Объявления ВКонтакте (далее – ВКО) мы реализовывали функциональность создания объявлений из ВКонтакте. В группах-барахолках ВКонтакте появилась кнопка «Разместить объявление», которая создавала товар на Юле и публиковала его на стене группы. При публикации в группе появлялся сниппет с фото, названием и ценой товара, ссылка в этом сниппете вела в Юлу. Поскольку у нас уже была реализована форма создания объявления в миниаппе услуг, было решено использовать его кодовую базу. Сама форма создания отличалась возможностью размещать товар в любой категории (не только заявки на услуги) и тем, что форма подачи в ВКО отображалась в цветах ВКонтакте. Сравнение формы подачи в миниаппе услуг и ВКО: Как говорилось выше, для написания стилей мы используем styled-components. В миниаппе услуг мы задавали тему через конфигурацию темы Юлы: В ВКО для того, чтобы задать тему, используются css-custom-properties, которые меняются в зависимости от темы ВКонтакте (темная или светлая): Кроме того, некоторые цвета, как и компоненты, по-разному выглядят в мобильной и десктопной версиях. Следующим этапом разработки миниаппа была реализация карточки товара, чтобы пользователи, которые переходят по сниппетам, не выходили из ВКонтакте на сайт или приложение Юлы, а оставались внутри ВКонтакте: Функциональность карточки товара мы также переиспользовали из миниаппа услуг. Карточка работала аналогично карточкам товара в приложении Юлы с поддержкой основных сценариев. Сравнение реализации карточки товара в миниаппе услуг и ВКО: Третьим этапом была разработка главной страницы ВКО, попасть на которую можно было из раздела сервисов ВКонтакте. Эту функциональность пришлось делать практически с нуля, потому что реализация фильтрации объявлений в услугах и ВКО сильно различалась. В миниаппе услуг обращение к ленте делалось через REST, а в ВКО — через GraphQL. Реализация ленты товаров через GraphQL достаточно удобная, потому что позволяет отображать в ленте произвольные элементы, отличные от товаров: рекламные карточки, различные горизонтальные растяжки, премиум-карточки платных клиентов Юлы. Лента Юлы позволяет показывать товары, которые находятся недалеко от пользователя, в каждой карточке указано расстояние в километрах. Если пользователь разрешил приложению ВКонтакте доступ к своему местоположению, мы показываем товары на определённой удалённости от точки, в которой находится пользователь. Если же он запретил доступ к координатам, то мы берем их из профиля пользователя в Юле или предлагаем ему указать своё местоположение.  Фильтры позволяют пользователю искать товары по конкретной категории/подкатегории и местоположению. Кроме того, для каждой категории мы используем дополнительные атрибуты фильтрации. Например, для мобильных телефонов это операционная система, модель, диагональ экрана. Суммарно разработка первых трёх фаз ВКО заняла три месяца. Полноценный запуск раздела состоялся 1 декабря 2020 года. Сегодня любой пользователь ВКонтакте может воспользоваться нашим сервисом не выходя из приложения ВКонтакте. А каждая группа может подключить у себя раздел Объявления для увеличения охвата аудитории. Помимо мобильной версии, недавно состоялся запуск десктопной версии Объявлений. Она не реализована на технологии миниаппов, а нативно встроено в сайт ВКонтакте. Это позволяет пользоваться нашим сервисом на всех платформах.