Перейти к содержимому

Мониторинг изменений страницы (Content monitor)

Контент-монитор следит не за доступностью ресурса, а за содержимым: Notifly раз в N секунд загружает заданный URL, извлекает из ответа интересующее значение и сравнивает его с предыдущим. Как только значение изменилось — приходит alert. Это активный монитор (звонит сам Notifly), но он отвечает на вопрос «что изменилось на странице», а не «жив ли сайт».

Типичные задачи:

  • Цена — отслеживать цену товара на странице магазина или у конкурента.
  • Статус / наличие — «в наличии» ↔ «нет в наличии», статус заказа, статус сервиса.
  • Контент конкурента — появилась новая запись в блоге, изменился прайс, обновился changelog.
  • JSON API — значение поля в публичном JSON-ответе (курс, остаток, версия).

Что именно сравнивать, задаёт режим (mode). Поддерживаются пять режимов:

modeЧто извлекаетсяПоле selector
hashSHA-256 всего тела ответа — alert при любом изменении страницыне нужен
jsonЗначение по JSONPath из JSON-ответаобязателен — JSONPath, например $.price или $.items.0.status
textПодстрока по регулярному выражению из текста ответаregex; если пуст — ведёт себя как hash
cssТекст первого элемента по CSS-селекторуобязателен — валидный CSS-селектор
xpathТекст первого узла по XPath-выражениюобязателен — валидное XPath-выражение

Логика проверки одинакова для всех режимов: извлекаем значение → сравниваем с сохранённым lastValue → если отличается, отправляем alert и запоминаем новое значение. Первая проверка просто запоминает текущее значение и алерт не шлёт.

Вместо одиночного mode+selector можно задать массив правил (rules) — до 20 штук на один монитор. Каждое правило — это { "mode", "selector", "label" }, где label — необязательное человекочитаемое имя. Alert срабатывает, если изменилось хотя бы одно правило. Это удобно, когда на одной странице нужно следить сразу за несколькими значениями (например, цена + наличие + рейтинг).

"rules": [
{ "mode": "css", "selector": ".product-price", "label": "Цена" },
{ "mode": "css", "selector": ".availability", "label": "Наличие" },
{ "mode": "text", "selector": "Скидка\\s+\\d+%", "label": "Скидка" }
]

Если rules задан, поля верхнего уровня mode/selector игнорируются. Если rules пуст — работает одиночный режим (mode+selector), который остаётся для обратной совместимости.

По умолчанию страница загружается обычным HTTP-GET. Если нужное значение подгружается скриптами уже в браузере (SPA, ленивая подгрузка цены и т.п.), включите флаг useBrowser: true — тогда страница рендерится через headless Chromium, и значения извлекаются из готового DOM после выполнения JS.

Прежде чем создавать монитор, удобно подобрать и проверить правило «на лету» — для этого есть два эндпоинта, не требующие создания монитора.

Загружает страницу и применяет одно правило, возвращая извлечённое значение или понятную ошибку:

Окно терминала
curl -X POST "$NOTIFLY_URL/content-monitor/test-rule" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <client-token>" \
-d '{
"url": "https://example.com/product/42",
"useBrowser": false,
"mode": "css",
"selector": ".product-price"
}'
# → {"ok":true,"value":"1 299 ₽"}

Ответ: ok (булево), value (извлечённое значение, усечено до 200 символов), error (текст ошибки, если правило не сработало) и note (диагностика, например о деградации браузерного режима до GET).

Подобрать селектор нейросетью — POST /content-monitor/suggest-selector

Заголовок раздела «Подобрать селектор нейросетью — POST /content-monitor/suggest-selector»

Notifly загружает страницу один раз, сжимает HTML и одним запросом к LLM подбирает режим и селектор под ваше описание. Результат всегда проверяется на реальном содержимом страницы, поэтому в ответе гарантированно валидный sampleValue:

Окно терминала
curl -X POST "$NOTIFLY_URL/content-monitor/suggest-selector" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <client-token>" \
-d '{
"url": "https://example.com/product/42",
"useBrowser": false,
"prompt": "следить за ценой товара"
}'

В ответе: mode, selector, label, sampleValue (текущее значение на странице), reason (почему так), confidence (high/medium/low), alternatives (другие кандидаты) и fallback (true, если LLM недоступен и селектор подобран эвристикой). Поле prompt — до 500 символов. Запрос вида «следить за всей страницей» сразу вернёт режим hash без обращения к LLM.

  1. Откройте app.notifly.ruМониторы → Контент.
  2. Укажите URL, выберите режим (или нажмите «Подобрать селектор» и опишите словами, за чем следить), при необходимости включите useBrowser.
  3. Кнопкой «Проверить» убедитесь, что извлекается ровно то значение, которое нужно.
  4. Задайте период, текст alert и приоритет — и сохраните.

Одиночный режим (следим за одним CSS-значением):

Окно терминала
curl -X POST "$NOTIFLY_URL/content-monitor" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <client-token>" \
-d '{
"appid": 12345,
"name": "Цена товара #42",
"url": "https://example.com/product/42",
"mode": "css",
"selector": ".product-price",
"useBrowser": false,
"intervalSec": 3600,
"timeoutSec": 15,
"alertMessage": "Цена товара #42 изменилась!",
"alertPriority": 7
}'

Множественный режим (несколько правил на одной странице):

Окно терминала
curl -X POST "$NOTIFLY_URL/content-monitor" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <client-token>" \
-d '{
"appid": 12345,
"name": "Карточка товара",
"url": "https://example.com/product/42",
"rules": [
{ "mode": "css", "selector": ".product-price", "label": "Цена" },
{ "mode": "css", "selector": ".availability", "label": "Наличие" }
],
"intervalSec": 3600,
"alertMessage": "Изменилось содержимое карточки товара.",
"alertPriority": 5
}'

Мониторинг поля в JSON API:

Окно терминала
curl -X POST "$NOTIFLY_URL/content-monitor" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <client-token>" \
-d '{
"appid": 12345,
"name": "Курс из API",
"url": "https://api.example.com/rates",
"mode": "json",
"selector": "$.usd.value",
"intervalSec": 600,
"alertMessage": "Курс USD изменился."
}'
ПолеТипОбязательноОписание / ограничения
appiduintдаID приложения (канала), куда слать alert
namestringдаНазвание монитора, 1–200 символов
urlstringдаВалидный http(s)-URL
modestringда*Одиночный режим: hash / json / text / css / xpath
selectorstringзависитJSONPath для json, regex для text, CSS для css, XPath для xpath; для json/css/xpath обязателен
rulesarrayда*Массив правил {mode, selector, label}, до 20; альтернатива mode+selector
useBrowserboolнетtrue — рендеринг через headless Chromium
intervalSecuintдаПериод проверки, 60–86400 секунд
timeoutSecuintнетТаймаут загрузки, по умолчанию 15, максимум 60
alertMessagestringдаТекст уведомления, 1–2000 символов
alertTitlestringнетЗаголовок уведомления
alertMessageMarkdownboolнетТрактовать текст alert как Markdown
alertPriorityintнетПриоритет уведомления, 0–10

* Нужно задать либо rules (множественный режим), либо mode+selector (одиночный). Если rules непуст — mode/selector игнорируются.

Новый монитор создаётся со статусом pending и проверяется почти сразу (nextCheckAt = «сейчас»). После изменения «значимых» полей (URL, режим, селектор, правила, useBrowser, период, таймаут) проверка перепланируется на «сейчас», косметические правки (название, заголовок/текст alert, приоритет) расписание не сдвигают.

  • POST /content-monitor/:id/pause — приостановить (проверки не выполняются; nextCheckAt отодвигается далеко в будущее).
  • POST /content-monitor/:id/resume — возобновить (статус снова pending, проверка планируется на «сейчас»).

В записи монитора хранятся lastValue (последнее извлечённое значение), lastError (последняя ошибка загрузки/извлечения), lastCheckAt, nextCheckAt и alertedAt.

  • Период проверки: 60–86400 секунд (от 1 минуты до 24 часов).
  • Таймаут загрузки: по умолчанию 15 с, максимум 60 с.
  • До 20 правил на один монитор.
  • Приоритет alert: 0–10; длина name — 1–200, alertMessage — 1–2000 символов.
  • Запросы идут из облака, поэтому целевой URL должен быть доступен из публичного интернета.
  • Браузерный режим (useBrowser) работает, только если на сервере настроен соответствующий контейнер.

Все эндпоинты требуют клиентский токен (или MCP-код с правом записи для изменяющих операций); список доступен и в режиме чтения. Подробнее о токенах — в Первый вход.

МетодПутьОписание
GET/content-monitorСписок контент-мониторов пользователя
POST/content-monitorСоздать монитор
POST/content-monitor/suggest-selectorПодобрать режим + селектор нейросетью по описанию
POST/content-monitor/test-ruleПрименить одно правило к странице (dry-run), вернуть значение или ошибку
PUT/content-monitor/:idОбновить настройки (нельзя сменить appid)
DELETE/content-monitor/:idУдалить монитор
POST/content-monitor/:id/pauseПриостановить проверки
POST/content-monitor/:id/resumeВозобновить проверки

См. также: Активные мониторы, HTTP-мониторы, Workflow-мониторы, Browser-workflow.