Browser-workflow мониторы (автоматизация браузера)
Обычный HTTP-монитор и content-монитор видят только тот HTML, что сервер отдал в первом ответе. Для современных SPA, страниц с тяжёлым JavaScript и всего, что прячется за авторизацией, этого мало: нужный текст появляется только после логина, нескольких кликов и отрисовки фронтендом.
Browser-workflow монитор прогоняет заданную последовательность действий в настоящем headless Chromium — как маленький Selenium-сценарий — и проверяет, что сценарий по-прежнему доходит до конца. Если любой шаг падает (элемент пропал, текст не совпал, страница не загрузилась) — приходит alert. Дополнительно монитор умеет извлекать текст со страницы и слать уведомление при его изменении.
Из чего состоит сценарий
Заголовок раздела «Из чего состоит сценарий»Монитор описывается полями:
startUrl— начальный URL (обязателен, толькоhttp/https). С него начинается каждый прогон.steps— JSON-массив шагов, от 1 до 20 штук. Выполняются строго последовательно.cookies— опционально: захваченная сессия для авторизованных сценариев (см. ниже). Хранится в зашифрованном виде и наружу никогда не отдаётся.proxy— опциональный egress-проксиscheme://[user:pass@]host:portдля сайтов, режущих IP датацентра. Пусто — прямое соединение.timeoutSec— таймаут на один шаг. По умолчанию60, максимум120.intervalSec— как часто прогонять сценарий. Минимум 300 (5 минут), максимум86400(сутки).alertMessage(обязателен, до 2000 символов),alertTitle,alertMessageMarkdown,alertPriority(0…10) — что и с каким приоритетом слать при падении.notifyOnChange/notifyOnChangeVars— режим «уведомлять при изменении» извлечённых значений (см. ниже).
Шаг (BrowserStep)
Заголовок раздела «Шаг (BrowserStep)»Каждый элемент массива steps — это объект:
| Поле | Назначение |
|---|---|
name | человеко-читаемое имя шага (обязательно, попадает в alert при падении) |
description | описание шага на естественном языке — по нему ИИ подбирает action + selector |
action | действие (см. таблицу ниже) |
selector | CSS-селектор цели |
value | значение: URL / текст / клавиша; поддерживает подстановку {{переменная}} |
extractName | имя переменной для extractText |
auth | шаг авторизации: выполняется только при невалидной сессии |
Действия (actions)
Заголовок раздела «Действия (actions)»Поддерживаются ровно девять действий:
action | Что делает | Нужен selector | Нужен value |
|---|---|---|---|
navigate | перейти на URL (value = URL) | — | да (URL) |
click | кликнуть по элементу | да | — |
type | ввести value в поле | да | текст |
select | выбрать value в <select> | да | значение опции |
press | нажать клавишу value (например Enter) | — | клавиша |
waitFor | дождаться появления селектора | да | — |
assertText | проверить, что текст селектора содержит value | да | ожидаемый текст |
extractText | извлечь текст селектора в переменную extractName | да | — |
scroll | прокрутить страницу: value = top | bottom либо пиксели (300 вниз, -300 вверх) | — | — |
Шаги click, type, select, waitFor, assertText, extractText
требуют непустой selector — без него создание/обновление монитора вернёт
400. Для navigate обязателен value (URL). Для extractText обязателен
extractName.
Пример массива шагов
Заголовок раздела «Пример массива шагов»Проверяем, что после логина в личном кабинете виден баланс и он не «0»:
[ {"name": "Открыть дашборд", "action": "waitFor", "selector": "#dashboard"}, {"name": "Раскрыть счёт", "action": "click", "selector": "button.account-toggle"}, {"name": "Дождаться баланса", "action": "waitFor", "selector": ".balance-value"}, {"name": "Проверить, что не пусто", "action": "assertText", "selector": ".balance-value", "value": "₽"}, {"name": "Запомнить баланс", "action": "extractText", "selector": ".balance-value", "extractName": "balance"}]ИИ-подбор шага (build-step)
Заголовок раздела «ИИ-подбор шага (build-step)»Вручную подбирать CSS-селекторы скучно и хрупко. Поэтому есть эндпоинт
POST /browser-workflow/build-step: вы описываете шаг словами
(description), а ИИ сам подбирает action и стабильный selector, после чего
тут же проверяет кандидата в реальном браузере и возвращает результат.
Как это работает под капотом:
- Сервис открывает
startUrl, применяет переданныеcookiesи воспроизводит уже подтверждённыеsteps— получая актуальное состояние страницы. - LLM по описанию и разметке страницы предлагает действие и до трёх ранжированных селекторов-кандидатов.
- Кандидаты дёшево предвалидируются по HTML (синтаксис + наличие на странице), затем все проверяются за один прогон браузера.
- Если действие сработало — возвращается
verified: trueвместе с примером значения (sampleValue) дляextractText/assertText. Если нет — последнее предложение сverified: falseи пояснением вnote.
Тело запроса:
{ "startUrl": "https://app.example.com/login", "steps": [ /* уже подтверждённые шаги */ ], "description": "нажать кнопку «Войти»", "cookies": [ /* опционально: сохранённая сессия */ ], "proxy": "", "sessionId": "", "timeoutSec": 60}Ответ:
{ "action": "click", "selector": "button[type=submit]", "value": "", "extractName": "", "label": "Войти", "reason": "...", "sampleValue": "", "verified": true, "availableVars": ["balance"], "cookies": [ /* итоговые cookies сессии */ ]}Поле description — от 1 до 500 символов. availableVars показывает переменные,
которые уже извлечены предыдущими шагами (через extractText) и доступны для
подстановки {{var}} на этом шаге. Возвращаемые cookies стоит накапливать на
клиенте и передавать в следующий build-step, чтобы авторизованные шаги не
пришлось переигрывать заново.
Авторизованные сценарии: захват cookies
Заголовок раздела «Авторизованные сценарии: захват cookies»Чтобы мониторить страницы за логином, нужна валидная сессия. Эндпоинт
POST /browser-workflow/login выполняет шаги логина (type пароля, click
кнопки и т.п.) в headless-браузере и возвращает итоговые cookies в открытом
виде — вы затем передаёте их в поле cookies при создании/обновлении монитора,
где они шифруются перед сохранением.
curl -X POST "$NOTIFLY_URL/browser-workflow/login" \ -H "X-Notifly-Key: C..." \ -H "Content-Type: application/json" \ -d '{ "startUrl": "https://app.example.com/login", "steps": [ {"action": "type", "selector": "#email", "value": "me@example.com"}, {"action": "type", "selector": "#password", "value": "secret"}, {"action": "click", "selector": "button[type=submit]"} ], "timeoutSec": 60 }'Ответ:
{ "cookies": [ /* массив cookie */ ], "count": 7, "url": "https://app.example.com/dashboard" }Тестовый прогон (test-step)
Заголовок раздела «Тестовый прогон (test-step)»Перед сохранением весь сценарий целиком можно прогнать через
POST /browser-workflow/test-step — это «кнопка Проверить». Сервис выполняет все
шаги и сообщает, дошёл ли до конца.
curl -X POST "$NOTIFLY_URL/browser-workflow/test-step" \ -H "X-Notifly-Key: C..." \ -H "Content-Type: application/json" \ -d '{ "startUrl": "https://app.example.com/dashboard", "cookies": [ /* сохранённая сессия */ ], "steps": [ /* весь сценарий */ ], "timeoutSec": 60 }'Ответ:
{ "ok": true, "failedStep": -1, "error": "", "url": "https://app.example.com/dashboard", "cookies": [ /* итоговые cookies всей сессии */ ], "count": 7, "vars": { "balance": "12 340 ₽" }}Если сценарий упал, ok: false, а failedStep укажет индекс сломавшегося шага и
error — причину. При успехе vars содержит все извлечённые extractText
значения — удобно сразу проверить, что забирается именно то, что нужно.
Режим «уведомлять при изменении»
Заголовок раздела «Режим «уведомлять при изменении»»Если включить notifyOnChange, монитор работает не как «упал/не упал», а как
трекер значений: после каждого успешного прогона он сравнивает извлечённые
(extractText) переменные с прошлым успешным прогоном и шлёт уведомление, когда
любое из них изменилось.
notifyOnChangeVars— JSON-массив имён переменных для отслеживания. Пустой массив = следить за всеми извлечёнными переменными.
Так, например, можно ловить изменение цены товара, статуса заказа или остатка на складе на странице, которая рендерится только в браузере.
Статусы и пауза
Заголовок раздела «Статусы и пауза»Монитор создаётся со статусом pending и первой проверкой «на сейчас». Дальше
он переходит в up / down (а также degraded) по результатам прогонов.
Поставить на паузу и снять с паузы можно эндпоинтами
POST /browser-workflow/:id/pause (статус paused) и
POST /browser-workflow/:id/resume (возврат в pending). На паузе сценарий не
прогоняется и алертов не шлёт.
При падении в карточке монитора видны lastError и lastFailedStep — текст
последней ошибки и имя сломавшегося шага.
REST API
Заголовок раздела «REST API»Все эндпоинты требуют client-token (где помечено «write» — токен с правом записи
или MCP-код с доступом на запись). В ответах списка зашифрованные cookies
вырезаются; вместо них отдаётся флаг hasCookies.
| Метод и путь | Авторизация | Назначение |
|---|---|---|
GET /browser-workflow | client-token | список мониторов (без cookies) |
POST /browser-workflow | client-token (write) | создать монитор |
PUT /browser-workflow/:id | client-token (write) | обновить монитор |
DELETE /browser-workflow/:id | client-token (write) | удалить монитор |
POST /browser-workflow/:id/pause | client-token (write) | поставить на паузу (status=paused) |
POST /browser-workflow/:id/resume | client-token (write) | снять с паузы (status=pending) |
POST /browser-workflow/build-step | client-token (write) | ИИ-подбор и проверка одного шага |
POST /browser-workflow/login | client-token (write) | прогнать логин и вернуть cookies сессии |
POST /browser-workflow/test-step | client-token (write) | тестовый прогон всего сценария |
Пример: создание монитора
Заголовок раздела «Пример: создание монитора»curl -X POST "$NOTIFLY_URL/browser-workflow" \ -H "X-Notifly-Key: C..." \ -H "Content-Type: application/json" \ -d '{ "appid": 12, "name": "Баланс в ЛК", "startUrl": "https://app.example.com/dashboard", "steps": "[{\"name\":\"Дождаться баланса\",\"action\":\"waitFor\",\"selector\":\".balance-value\"},{\"name\":\"Запомнить баланс\",\"action\":\"extractText\",\"selector\":\".balance-value\",\"extractName\":\"balance\"}]", "cookies": "[ /* plaintext cookies из /login */ ]", "intervalSec": 900, "timeoutSec": 60, "notifyOnChange": true, "alertMessage": "Сценарий «Баланс в ЛК» сломался" }'См. также: Активные мониторы · Content-монитор · Workflow-монитор (HTTP) · Полный API.