К содержанию
ActionPulse

Уведомления и вебхуки

Пять типов правил оповещений ActionPulse, каналы email, Telegram и webhook, формат и подпись вебхука, недельная сводка и идемпотентные отметки релизов из CI/CD.

Кому
Тем, кто хочет узнавать об изменениях без ежедневных проверок
Проверено
На этой странице

Оповещение — это правило, которое сервер проверяет по расписанию и, если условие выполнилось, отправляет уведомление в указанные каналы. В отличие от панели, ему не нужна открытая страница.

Раздел — Мониторинг → Оповещения. Там же настраивается недельная сводка.

Пять типов правил

Мастер начинается с выбора типа. Их ровно пять, и они отвечают на разные вопросы.

Тип Отвечает на вопрос Что задаёте
Метрика «число вышло за порог?» метрика, событие, фильтры, окно, условие, порог
Нет событий «трекер молчит?» окно тишины в минутах
Падение воронки «конверсия шага просела?» сохранённая воронка, переход, окно, порог конверсии
Сезонная аномалия «день выбился из своей обычной картины?» базовая линия, чувствительность, направление
Качество данных «разметка ломается?» окно проверки реестра событий

Метрика

Метрика — «События» или «Уникальные пользователи». Окно — 5, 15, 60 или 240 минут (по умолчанию 60). Условие — «Больше» или «Меньше» (по умолчанию «Меньше»), порог — любое число. Событие по умолчанию любое, можно выбрать конкретное и добавить фильтры.

Типовая формулировка: «уникальных плательщиков за час стало меньше 10».

Нет событий

Единственное поле — «Окно тишины, минут»: минимум 5, по умолчанию 30. Правило срабатывает, если за окно не пришло ни одного события.

Это самое дешёвое правило в продукте и самое полезное сразу после подключения: именно оно сообщает, что разметка отвалилась при релизе.

Падение воронки

Нужна уже сохранённая воронка минимум с двумя шагами — иначе мастер честно скажет «Нет сохранённых воронок с двумя и более шагами». Дальше выбираются переход «шаг A → шаг B», окно 1, 24 или 72 часа (по умолчанию 24) и порог конверсии в процентах.

Шаги воронки копируются в правило в момент сохранения. Если потом поменять отчёт, правило продолжит проверять прежнюю цепочку.

Сезонная аномалия

Сравнивает завершённые дни либо с теми же днями недели, либо со скользящим окном предыдущих дней. Гранулярность — сутки; текущий неполный день в расчёт не входит, нулевое значение считается наблюдением, а отсутствующий день — пропуском.

  • Чувствительность подписана прямо в интерфейсе: высокая — |z| ≥ 2, средняя — |z| ≥ 3 (по умолчанию), низкая — |z| ≥ 4.
  • Направление — рост и падение, только рост или только падение.
  • Разовые окна подавления и еженедельные окна обслуживания — чтобы регулярная выгрузка по субботам не звонила каждую неделю.

Есть исторический предпросмотр: диапазон от 1 до 90 завершённых дней, тот же расчёт, cooldown и подавления, что у рабочего правила, без создания событий. Результат всегда помечен «Оценка».

Языковые модели в расчёте не используются — только детерминированные правила.

Качество данных

Реагирует на предупреждающие и критические сигналы реестра событий. Окно — 15 минут, 1 час, 4 часа, 24 часа или 7 дней (по умолчанию 1 час). Сигналы «мало данных» игнорируются, чтобы правило не звонило на тишине.

Мастер: три шага

Тип → Условие → Каналы.

На шаге «Условие» кроме параметров типа есть два общих поля:

  • «Проверять» — каждую минуту, каждые 5 минут или каждые 15 минут (по умолчанию 5 минут).
  • «Пауза после срабатывания» — 1 час, 6 часов или сутки (по умолчанию 1 час). Пока пауза идёт, повторное срабатывание уведомление не отправит.

Каналы на третьем шаге необязательны: правило без каналов будет исправно писать историю срабатываний и никому ничего не пришлёт. Это нормальный способ сначала посмотреть, как правило ведёт себя на ваших данных.

Кнопка «Отправить тест» активна только у сохранённого правила без несохранённых правок. Она отправляет настоящее уведомление во все каналы, помечает событие в истории бейджем «ТЕСТ», а в теле вебхука ставит "test": true. В ответе видно по каждому каналу: доставлено или нет, сколько было попыток и с каким кодом ответил получатель.

Каналы доставки

Каналов ровно три, и в одном правиле их суммарно не больше восьми.

Канал Что указываете Предел
Email адрес получателя 320 символов
Telegram chat_id 128 символов
Webhook HTTPS-адрес и секрет подписи адрес 2048, секрет 4096 символов

chat_id для Telegram выдаёт бот: напишите @ActionPulseBot команду /start, затем /link с идентификатором проекта — бот ответит числом, которое нужно вставить в поле.

Адрес вебхука должен быть http- или https-ссылкой без логина и пароля и без якоря. В облаке принимаются только публичные HTTPS-адреса; в on-prem политику задаёт администратор установки.

При понижении тарифа существующие правила остаются видимыми и удаляемыми — их не удаляют молча. Недоступный webhook в правиле можно только убрать кнопкой «Удалить webhook из правила»; пока он там, правило не сохранится.

Формат вебхука

Уведомление приходит одним POST с Content-Type: application/json и User-Agent: ActionPulse-Webhook/1. Два заголовка несут смысл:

Заголовок Значение
X-PP-Signature sha256= и 64 строчных hex-символа
X-PP-Event-ID идентификатор события, совпадает с event_id в теле

Тело:

{
  "version": "1",
  "event_id": "8b0d3f2e-1c4a-4f0e-9b1d-2a3c4d5e6f70",
  "rule": {
    "id": 41,
    "project_id": 7,
    "name": "Заказы упали",
    "type": "metric_threshold",
    "config": { "metric": "events", "event": "order_created", "window_minutes": 60, "op": "lt", "threshold": 10 }
  },
  "value": 4,
  "message": "order_created за 60 мин: 4 < 10",
  "fired_at": "2026-07-28T09:12:03.418271Z",
  "test": false
}

value может быть null — например, когда тип правила не выражается одним числом. fired_at — всегда UTC. config — конфигурация правила как есть; для правила без конфигурации приходит {}.

Проверка подлинности

Подпись — HMAC-SHA256 по точным байтам тела с ключом, который вы задали в поле «Секрет подписи». Значение заголовка — строка sha256= плюс hex.

Считайте подпись до разбора JSON: любое переформатирование тела (смена порядка ключей, отступы, замена кодировки) сломает проверку.

Node.js

import crypto from 'node:crypto'

// rawBody — именно байты запроса, а не результат JSON.parse.
export function verifyAlert(rawBody, signatureHeader, secret) {
  const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex')
  const a = Buffer.from(expected)
  const b = Buffer.from(signatureHeader ?? '')
  return a.length === b.length && crypto.timingSafeEqual(a, b)
}

Python

import hashlib
import hmac

def verify_alert(raw_body: bytes, signature_header: str, secret: str) -> bool:
    digest = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(f"sha256={digest}", signature_header or "")

Сравнивайте постоянным по времени сравнением (timingSafeEqual, hmac.compare_digest), а не обычным ==.

Повторы

Параметр Значение
Попыток до 3
Таймаут одной попытки 5 секунд
Паузы между попытками 250 мс, затем 500 мс
Читается из ответа не более 64 КиБ

Повтор делается только на кодах 408, 425, 429 и любом 5xx. На 3xx и остальных 4xx повтора не будет — уведомление считается недоставленным.

Отвечайте 2xx быстро и обрабатывайте событие асинхронно: пять секунд — это весь бюджет попытки. Дедуплицируйте по X-PP-Event-ID: повтор после таймаута может прийти на уже обработанное событие.

Недельная сводка

Секция «Еженедельный дайджест» на той же странице. Отправка — каждый понедельник в 09:00 по часовому поясу проекта; сводка покрывает предыдущую полностью завершённую локальную неделю.

  • Каналы те же и с теми же пределами; всего не больше восьми. Несколько адресов вводятся с новой строки или через запятую.
  • Для включённой сводки нужен хотя бы один канал.
  • Две дополнительные секции — «Revenue» и «Топ rage-элемент». Если поставщик данных недоступен, секция честно скрывается, а не показывается нулём.
  • Предпросмотр считает ту же сводку тем же кодом, но никуда её не отправляет. Кнопка недоступна, пока есть несохранённые изменения.
  • Вебхук сводки подписывается тем же HMAC-SHA256 в X-PP-Signature.

История запусков показывает статус каждой недели: «В очереди», «Расчёт», «Доставка», «Готово», «Частично», «Ошибка», «Пропущено», «Неизвестно». Статус «Неизвестно» означает именно неизвестность: продукт не отправляет такую доставку повторно вслепую.

Настраивать сводку может аналитик и выше; наблюдатель видит настройки только для чтения.

Отметки релизов из CI/CD

Отметка релиза — вертикальная метка на графиках: на обзоре, в отчёте «Аналитика» и на блоках «Аналитика» сводных панелей. В карточке метки видно источник, версию, среду, автора и сравнение «Среднее до / после» с явной подписью «Корреляция, не причинность»; при недостатке точек графика показывается «Недостаточно точек графика с обеих сторон».

В кабинете отметки только читаются. Создаются они через API — сознательно: момент релиза знает ваш пайплайн, а не человек с мышкой.

Шаг 1. Выпустить release-токен

POST /api/v1/projects/YOUR_PROJECT_ID/release-tokens с телом {"name": "..."}, роль администратор или владелец. В ответе значение токена приходит один раз — дальше его не покажет никто.

Токен начинается с pp_rel_ и имеет единственное право release_markers:write. Он не принимается ни приёмом событий, ни остальными методами API: даже утёкший токен умеет только ставить отметки о деплое. Отзыв доступен всегда.

Шаг 2. Ставить отметку из пайплайна

curl -sS -X POST "https://YOUR_ACTIONPULSE_HOST/api/v1/projects/YOUR_PROJECT_ID/release-markers/deploy" \
  -H "Authorization: Bearer $ACTIONPULSE_RELEASE_TOKEN" \
  -H "Idempotency-Key: $CI_COMMIT_SHA" \
  -H "Content-Type: application/json" \
  -d '{
        "name": "web 2026.7.3",
        "ts": "2026-07-28T09:12:00Z",
        "version": "2026.7.3",
        "env": "production",
        "link": "https://example.com/ci/runs/4821"
      }'
Поле Обязательно Предел
name да 200 символов
ts да RFC 3339, время релиза
description нет 2000 символов
version нет 128 символов
env нет 128 символов
link нет абсолютный http(s)-адрес без логина и пароля, 2048 символов

Поле source присылать нельзя — его задаёт сервер, и у таких отметок источник всегда «CI/CD deploy».

Идемпотентность

Заголовок Idempotency-Key обязателен и должен быть ровно один. Значение — от 8 до 128 видимых символов ASCII (пробел и запятая не допускаются). SHA коммита или идентификатор запуска пайплайна подходят идеально.

Ответ Что произошло
201 отметка создана
200 с заголовком Idempotency-Replayed: true тот же ключ и то же тело — повтор, второй отметки не появилось
409 тот же ключ прислан с другим телом
429 превышен лимит 60 запросов в минуту (на адрес и на токен); в ответе есть Retry-After

Это единственный клиентский метод ActionPulse с заголовком Idempotency-Key — остальные методы полагаются на другие механизмы, см. идемпотентность и повторы. Практический смысл здесь прямой: перезапуск упавшего job’а в CI не наплодит четыре метки об одном релизе.

История срабатываний

Клик по строке правила открывает историю. Окно по умолчанию — последние 90 дней, страницами по 100 записей.

Колонки: «Когда» (с бейджем «ТЕСТ» у тестовых отправок), «Значение», «Сообщение», «Доставка». У сезонных правил добавляются «Расчёт» — наблюдение, база, z, порог и объём использованной истории — и «Обратная связь»: ложное срабатывание можно отметить с комментарием до 1000 символов.

Статусы доставки: ожидает, выполняется, завершена, пропущена и «Результат доставки неизвестен».

Удаление правила удаляет и его историю: «Правило «{name}» и его история срабатываний будут удалены».

Частые ошибки

  • Правило сохранено без каналов — история пишется, письма нет. Проверьте третий шаг мастера.
  • Ждали изменения частоты проверки — её нельзя поменять после сохранения, нужно новое правило.
  • Вебхук отвечает 403 или 404 — повтора не будет. Такие коды означают ошибку на принимающей стороне, а не временный сбой.
  • Вебхук отвечает медленнее пяти секунд — попытка обрывается по таймауту. Принимайте и обрабатывайте в фоне.
  • Подпись не сходится — почти всегда потому, что тело было разобрано и собрано заново. Считайте HMAC по сырым байтам.
  • Одно событие обработано дважды — используйте X-PP-Event-ID как ключ дедупликации.
  • Правило «Метрика» молчит, хотя метрика упала — проверьте, не идёт ли пауза после предыдущего срабатывания, и совпадает ли окно правила с реальным масштабом события.