Ни одну нельзя было увидеть без настоящего прогона: часть закрыта песочницей Яндекса, часть — швами между кусками, которые по отдельности покрыты тестами. 1. Слепок креативов уходил с SelectionCriteria пустым МАССИВОМ. Живой Яндекс отвечает отказом 8000 «SelectionCriteria cannot contain an array», портал не может снять слепок, задание роботу не выдаётся, клиент видит вечное «готовим картинки». В JSON нужен пустой ОБЪЕКТ. Песочница до этой проверки не доходила — отвергала запрос раньше, на входе. 2. Отказы Яндекса ПО ПОЗИЦИИ внутри ответа глотались молча. Запрос успешен, а нужного Id в позиции нет — вместо него Errors с человеческим объяснением. Портал падал ошибкой PHP «Undefined array key Id», ни клиенту, ни в журнал не попадало ни слова из ответа Яндекса. Теперь слова Яндекса выходят наружу — именно это и позволило найти пункт 3. 3. В условии ретаргетинга не передавался MembershipLifeSpan — срок хранения человека в сегменте. Живой Яндекс отказывает «Required field: Not specified time for goal or segment», и следом «Object not found»: довод негоден целиком, запуск встаёт. Берём audience_days кампании, границы Яндекса 1..540. 4. Робот не отдавал набор Яндексу: заливал файлы, нажимал «Создать» и уходил. Оказалось, «набор» в кабинете и «креатив» в creatives.get — разные вещи: пока набор не отмечен галочкой и не нажато «Добавить выбранные», Яндекс креативы не регистрирует. Замер: 14 залитых картинок были невидимы для creatives.get, после добавления в ЧЕРНОВИК формы счётчик прыгнул 18 -> 32 в ту же секунду. Объявление при этом не сохраняется, «Сохранить изменения» робот по-прежнему не трогает никогда. 5. Гонка при заливке. Три живых прогона подряд из 15 картинок доносили 14, и каждый раз пропадала ДРУГАЯ: 480x320, потом 300x600, потом 336x280. Замер объяснил: кнопка «Создать» разблокируется на 4-й секунде, когда принято 11 файлов из 15, остальные дозагружаются к 7-й. Робот жал сразу по разблокировке. Ждём теперь по строкам принятых файлов и по исчезновению слова «Загружается». Первая попытка этой починки НЕ РАБОТАЛА и выглядела рабочей: сторож считал размеры в окне, не заметив постоянного фильтра из тех же 15 размеров вверху. Поймано по тому, что прогон занял ровно столько же секунд, сколько до починки. Отсюда тире в признаке приёма — фильтр его не содержит. Каждая починка закрыта тестом, который сначала падал на своей поломке. Прежние тесты проверяли разбор ОТВЕТОВ и путь ДО «Создать» — форму запросов и то, что после, не смотрел никто. Робот 84 из 84, реклама портала 42 из 42. Проверено живьём на боевом: задание роботу отработало со статусом done, опознано 15 креативов из 15. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Робот-грузчик креативов в кабинет Яндекс Директа
Зачем он нужен
Портал заводит рекламную кампанию «за показы» в Яндексе целиком через программный
интерфейс — кроме одного шага. Картиночный креатив через него создать нельзя: приём
creatives.add принимает только видео, а конструктор креативов Яндекс закрыл 01.06.2026.
Остался единственный путь — загрузить готовые файлы руками в веб-кабинете.
Этот робот и есть «руки»: он относит готовые файлы клиента в кабинет и говорит порталу «готово». Всё остальное портал делает сам.
Что робот делает
- Спрашивает у портала, есть ли работа.
- Скачивает файлы баннеров.
- Открывает кабинет в своём браузере и проверяет, жив ли вход.
- Загружает файлы через «Загрузить креативы».
- Отчитывается порталу и чистит за собой скачанные картинки.
Чего робот НЕ делает
- Не создаёт кампаний и не запускает показы.
- Не тратит деньги — он вообще не может: таких действий у него нет.
- Не читает номера созданных креативов — их портал добывает сам, сравнивая список креативов кабинета до и после загрузки.
- Не нажимает «Сохранить изменения» — единственную кнопку, которая меняет кабинет. На это есть отдельный тест-сторож.
При любом сбое робот останавливается, отчитывается порталу «сбой» и шлёт письмо со снимком экрана. Кампания при этом остаётся черновиком.
Настройка
Скопировать .env.example в .env и заполнить. Отдельного пояснения стоят:
YC_CABINET_LOGIN— логин рекламного кабинета.YC_ANTEROOM_CAMPAIGN_IDиYC_ANTEROOM_GROUP_ID— «прихожая»: существующие кампания и группа, форму нового объявления которых робот открывает только чтобы добраться до окна загрузки. Ничего в них не сохраняется. Своей кампании у робота в этот момент ещё нет: портал ставит задание до создания кампании в Яндексе, потому что кампания заводится сразу с готовыми номерами креативов. Надёжнее всего назначить прихожей отдельную остановленную кампанию — тогда робот не приближается к работающей рекламе вовсе.
Как завести вход в кабинет
Вход заводится один раз глазами и дальше живёт в папке профиля браузера:
npm run login
На боевом сервере экрана нет, поэтому команда запускается внутри виртуального рабочего стола, к которому подключаются по удалённому рабочему столу через SSH-туннель. Наружу порт не открывается. Владелец вводит пароль и код из СМС — профиль сохраняется на диск.
Как запускать
npm run run:once # один проход: взять задание, если оно есть
npm run keepalive # тихо зайти в кабинет, чтобы вход не заснул
npm test # проверки, браузер не нужен
По расписанию: run:once — часто, keepalive — раз в ~15 минут.
Наложиться друг на друга они не могут: браузерный профиль один, и оба запуска берут общий
файл-замок robot.lock в папке робота. Занят замок — процесс молча уходит с кодом 0 и
пробует в следующий раз; задание при этом остаётся в очереди. Замок, брошенный убитым
процессом (перезагрузка сервера), перехватывается через полчаса.
Снимки экрана в папке screenshots/ робот убирает сам: старше двух недель — удаляет при
очередном запуске. Свежие нужны, чтобы разобрать вчерашний сбой; лежать вечно им нельзя —
на снимке видна боковая панель кабинета с логином и остатком счёта.
Пришло письмо-алярм — что делать
В письме указан шаг, на котором робот встал, и приложен снимок экрана.
- «Вход в кабинет слетел» — зайти по удалённому рабочему столу и выполнить
npm run login. - «Кабинет не принял файлы» — посмотреть снимок: скорее всего, файл не тех размеров или слишком тяжёлый.
- «Окно загрузки не закрылось» — в письме будет текст, который показал сам кабинет. Задание при этом закрыто как выполненное: правду об успехе знает портал, он сверяет список креативов до и после. Если креативы не появились, портал сам пометит задание сбойным.
🔑 Смотрите на концовку письма — она честно говорит, что происходило в кабинете:
- «Робот остановился и ничего в кабинете не менял» — работа не начиналась, кампания осталась черновиком, деньги не потрачены. В кабинет идти незачем.
- «Креативы в кабинет уже загружены» — робот дошёл до конца, файлы лежат в кабинете. Загляните туда и в очередь заданий: повторная заливка оставит дубли, а вычистить их можно только руками.
Где почитать подробности
- Разметка экранов кабинета, снятая живьём — docs/cabinet-flow.md.
- Замысел целиком —
docs/superpowers/specs/2026-07-27-yandex-creative-robot-design.md. - Почему конструктор закрыт —
docs/superpowers/findings/2026-07-27-yandex-konstruktor-zakryt/.