PPostmastersTool

Интеграции

Встройте мониторинг репутации в свои процессы: уведомления в email, Telegram и Slack, а для автоматизации — типизированные webhook-события с HMAC-подписью (n8n, Albato, SIEM, свой endpoint).

Каналы уведомлений

Email

Письма об инцидентах и отчёты. Простой режим — письма с адреса сервиса, свой SMTP — с вашего домена. Доп. получатели верифицируются кодом.

Telegram

Сервисный бот @postmasterstool_bot или свой бот: личные чаты и группы (включая супергруппы с темами).

Slack

Сообщения в канал через Incoming Webhook URL — Block Kit разметка, кнопка «Открыть инцидент».

Webhook

JSON POST на ваш HTTPS-endpoint: типизированные события v1, HMAC-SHA256 подпись, ретраи. Основа для n8n, Albato, SIEM и своих систем.

Формат webhook-событий (v1)

Каждая доставка — POST с JSON-конвертом. Поля subject/text/incidentUrl/timestamp сохраняются из первой версии формата; сверху добавлены v, event, occurredAt и (для части событий) data:

Конверт события (пример incident.created)
{
  "v": 1,
  "event": "incident.created",
  "occurredAt": "2026-07-26T10:15:00.000Z",
  "subject": "[CRITICAL] Gmail: вырос spam rate для example.com — INC-2026-000142",
  "text": "🔴 CRITICAL — вырос spam rate\nДомен: example.com\n…",
  "incidentUrl": "https://postmasterstool.com/incidents/7d2c…",
  "timestamp": "2026-07-26T10:15:00.000Z"
}

Типы событий

eventКогда отправляетсяdata
incident.createdНовый инцидент или переоткрытие после нарушения правила
incident.resolvedИнцидент закрыт (автовосстановление по гистерезису)
incident.reminderНапоминание по открытому инциденту (кулдаун 6 ч CRITICAL / 24 ч WARNING)
integration.errorТехническая проблема: сбой подключения, отзыв доступа, сломанный канал
report.readyОтчёт по расписанию сформирован и доставлен каналуscheduleName, periodStart, periodEnd, reportRunId
domain.risk_changedПереход risk-статуса домена green ↔ yellow ↔ red после прогона оценки алертовdomainId, domain, from, to, at
billing.eventБиллинговые уведомления (окончание trial, счета)
testТестовое уведомление кнопкой «Проверить» в настройках канала
Пример report.ready
{
  "v": 1,
  "event": "report.ready",
  "occurredAt": "2026-07-20T09:00:00.000Z",
  "data": {
    "scheduleName": "Еженедельный",
    "periodStart": "2026-07-13",
    "periodEnd": "2026-07-20",
    "reportRunId": "a41f…"
  },
  "subject": "Еженедельный отчёт PostmastersTool: 13.07 — 19.07",
  "text": "…",
  "incidentUrl": null,
  "timestamp": "2026-07-20T09:00:00.000Z"
}
Пример domain.risk_changed
{
  "v": 1,
  "event": "domain.risk_changed",
  "occurredAt": "2026-07-26T10:20:00.000Z",
  "data": {
    "domainId": "f5b5…",
    "domain": "example.com",
    "from": "green",
    "to": "yellow",
    "at": "2026-07-26T10:20:00.000Z"
  },
  "subject": "[WARNING] Статус риска домена example.com: green → yellow",
  "text": "…",
  "incidentUrl": "https://postmasterstool.com/domains/f5b5…",
  "timestamp": "2026-07-26T10:20:00.000Z"
}

occurredAt — момент наступления события, timestamp — момент отправки. Ретраи при недоступности: через 1 мин, 5 мин, 15 мин, 1 ч и 3 ч (6 попыток всего).

Проверка HMAC-подписи

Если в канале задан секрет, тело запроса подписывается HMAC-SHA256, заголовок X-PostmastersTool-Signature: sha256=<hex>. Подписывается сырое тело — проверяйте до парсинга JSON.

Node.js (Express)
const crypto = require('node:crypto');

function verifySignature(rawBody, signature, secret) {
  const expected =
    'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  const a = Buffer.from(signature ?? '', 'utf8');
  const b = Buffer.from(expected, 'utf8');
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

// Express: важно брать СЫРОЕ тело (express.raw), а не распарсенный JSON
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  if (!verifySignature(req.body, req.get('X-PostmastersTool-Signature'), SECRET)) {
    return res.sendStatus(401);
  }
  const event = JSON.parse(req.body.toString('utf8'));
  // …обработка event.event / event.data…
  res.sendStatus(200);
});
Python (Flask)
import hashlib, hmac, json
from flask import Flask, request

app = Flask(__name__)
SECRET = b'your-webhook-secret'

@app.post('/webhook')
def webhook():
    signature = request.headers.get('X-PostmastersTool-Signature', '')
    digest = hmac.new(SECRET, request.get_data(), hashlib.sha256).hexdigest()
    if not hmac.compare_digest(signature, 'sha256=' + digest):
        return 'invalid signature', 401
    event = json.loads(request.get_data())
    # …обработка event['event'] / event['data']…
    return 'ok', 200

Плейбуки

n8n

Триггер Webhook (POST, response «immediately») принимает событие; дальше Switch по полю event и HTTP Request node — в ваш API, Jira или Notion. Проверку подписи можно добавить Code-нодой (пример выше).

Albato

Связка с триггером «Входящий webhook»: URL из Albato — в настройки webhook-канала PostmastersTool. Поля event/data доступны в шагах сценария как переменные.

Slack Apps

Для Slack обычно достаточно родного канала SLACK (Incoming Webhook URL). Свой Slack App со своей логикой — принимайте generic webhook и шлите в chat.postMessage.

Свой endpoint

Требования: публичный HTTPS (приватные сети блокируются SSRF-гардом), ответ 2xx быстрее 10 секунд, редиректы не следуются. Делайте обработчик идемпотентным по паре event + occurredAt — ретрай пришлёт то же событие повторно.

Подключите свой первый webhook

Настройки → Уведомления → Новый канал → Webhook. Тестовое событие — кнопкой «Проверить».

Начать trial