Как работает API рендеринга Screenshots Live — Практическое руководство по автоматизации листингов в App Store
Техническое руководство о том, как API рендеринга Screenshots Live обрабатывает шаблоны, применяет переопределения YAML и генерирует готовые для магазина скриншоты — с реальными примерами кода и паттернами CI/CD для whitelabel-конфигураций.
Что рассматривается в этой статье
Если вы выпускаете whitelabel-приложения — или даже просто одно приложение с несколькими листингами в магазинах — вы, вероятно, уже столкнулись со проблемой скриншотов. Apple требует скриншоты для каждого размера устройства. Google Play — свой набор. Поддержка трёх языков утраивает нагрузку. Теперь умножьте это на количество брендовых вариантов, которые вы поддерживаете.
Предыдущая статья объясняла, почему существует Screenshots Live. Эта — практическое продолжение: как спроектирован API рендеринга, что он ожидает и как интегрировать его в ваш pipeline сборки, чтобы скриншоты перестали быть ручной задачей.
Как спроектирован pipeline рендеринга
Система рендеринга — это не синхронный эндпоинт в духе «отправить запрос, получить изображение». Это pipeline на основе задач, что важно, когда вы рендерите десятки или сотни скриншотов пакетно.
Вот поток:
- Вы отправляете запрос на рендеринг с ID шаблона и необязательными YAML-переопределениями (текст, скриншоты, рамки устройств — всё, что отмечено как заменяемое).
- Валидация — система проверяет, что ваш шаблон существует, что вы его владелец и что каждое переопределяемое поле действительно разрешено. URL-адреса проверяются на принадлежность к частным IP-диапазонам и ограниченным протоколам.
- Постановка в очередь — задача попадает в очередь BullMQ с бэкендом Redis. Ваш вызов API немедленно возвращает
jobIdи статусPending. Это ключевой момент: вы не ждёте завершения рендеринга. - Рендеринг — воркер на Rust подхватывает задачу, получает шаблон и изображения (с LRU-кэшем для повторных рендеров), загружает шрифты, рендерит canvas с помощью Skia и генерирует результат.
- Упаковка — отрендеренные изображения архивируются в ZIP и загружаются в объектное хранилище.
- Загрузка — вы опрашиваете эндпоинт статуса. Когда статус
Completed, обращаетесь к эндпоинту загрузки за предподписанным URL (действителен 1 час).
Асинхронный дизайн — намеренный. Когда нужно отрендерить 50 шаблонов для релиза, вы запускаете их все сразу, а затем собираете результаты. Никаких блокировок, никаких таймаутов.
Аутентификация
Для доступа к API рендеринга нужен аккаунт Pro. Создайте API-ключ в дашборде — он будет выглядеть как sa_live_.... Каждый запрос использует его как Bearer-токен:
Authorization: Bearer sa_live_your_key_here
Шаблоны: как они устроены
Всё вращается вокруг шаблонов. Шаблон — это canvas, который вы создаёте в визуальном редакторе: размещаете текстовые блоки, рамки устройств, изображения и устанавливаете фоны. Каждый элемент на canvas — это item с уникальным UUID.
Для автоматизации ключевая концепция — это заменяемые поля. Не каждое свойство каждого элемента можно переопределить через API. Администратор настраивает, какие поля можно менять — содержимое текста, семейство шрифтов, размер шрифта, цвета, URL скриншотов, ID рамок устройств и так далее. Это намеренное ограничение: оно предотвращает случайное нарушение макета потребителями API путём изменения позиций или размеров, которые дизайнер зафиксировал.
Думайте об этом как о договоре между дизайнером и pipeline: дизайнер владеет макетом, pipeline — контентом.
Система YAML-переопределений
Это ядро API. Вместо рендеринга шаблона точно так, как он сохранён, вы POST-ите YAML, который переопределяет конкретные поля конкретных элементов.
Шаг 1: Получите YAML-скаффолд
Каждый шаблон имеет эндпоинт скаффолда, возвращающий все заменяемые поля в виде закомментированного YAML:
curl -H "Authorization: Bearer sa_live_your_key_here" \
https://api.screenshots.live/templates/YOUR_TEMPLATE_ID/yaml
Шаг 2: Отправьте запрос на рендеринг
curl -X POST https://api.screenshots.live/render/api \
-H "Authorization: Bearer sa_live_your_key_here" \
-H "Content-Type: text/yaml" \
-d 'templateId: "550e8400-e29b-41d4-a716-446655440000"
items:
- itemId: "7c9e6679-7425-40de-944b-e07fc1f90ae7"
type: Text
text: "Отслеживайте ваши доставки"
color: "#1A73E8"'
Шаг 3: Опросите статус
curl -H "Authorization: Bearer sa_live_your_key_here" \
https://api.screenshots.live/render/api/JOB_ID
Статус прогрессирует: Pending → Active → Completed (или Failed, если что-то пошло не так). Для большинства шаблонов рендеринг занимает несколько секунд.
Шаг 4: Загрузите
curl -H "Authorization: Bearer sa_live_your_key_here" \
https://api.screenshots.live/render/JOB_ID/download
Возвращает предподписанный URL. Загрузка — это ZIP с вашими отрендеренными изображениями.
Прямая загрузка скриншотов
Вам не нужно где-то хостить скриншоты только для того, чтобы передать URL. Эндпоинт /render/api/with-pictures принимает multipart-загрузки. Можно прикрепить до 200 файлов по 10 МБ каждый. Это делает API практичным для CI/CD — ваш pipeline захватывает скриншоты, и вы отправляете их прямо в рендеринг без промежуточного хранилища.
Замена рамок устройств
Рамки устройств — это overlay-макеты: iPhone 16 Pro, Pixel 9, iPad Air, Galaxy S24. Они предзагружены в вашем аккаунте и указываются через UUID. Один шаблон может рендериться с разными рамками через переопределение frameId. Именно так вы обрабатываете разделение App Store и Google Play. Тот же макет шаблона, тот же скриншот, другая рамка.
Лимиты запросов и квоты
- API рендеринга: 5 запросов в 60 секунд
- Опрос статуса: 60 запросов в 60 секунд
- Дневные рендеры: 100 в день на уровне Pro
- Загрузка изображений: макс. 200 файлов на запрос, 10 МБ каждый
Валидация YAML
YAML-парсер намеренно строгий: без якорей, без алиасов, без кастомных тегов, макс. 1 МБ. Если что-то не так, сообщение об ошибке скажет точно что — неправильное имя поля, незаменяемое поле, неверный формат UUID, URL, указывающий на частный IP-диапазон. Спроектировано, чтобы быстро и ясно проваливаться — это важно, когда вы отлаживаете CI-pipeline в 23:00.