4.9.10. Вебхуки для почты

Внимание!

Только для корпоративной почты.

Примечания:

  • Запросы отправляются с User-Agent adm.tools mail webhook.
  • Если запрос не получил ответ 200, через 15 минут выполняется одна повторная отправка (видна в логе последних запросов).

Принцип работы вебхуков следующий:

  1. Вы создаёте вебхук, выбираете события, при которых он должен срабатывать, и указываете адрес, куда должен отправляться запрос.
  2. По указанному адресу размещаете скрипт, который будет принимать и обрабатывать запрос от вебхука (см. пример скрипта).
  3. Далее, когда в почтовом ящике наступает выбранное событие (например, поступает новое письмо), то сервер автоматически отправляет запрос скрипту по указанному адресу.
  4. Скрипт принимает запрос и выполняет действия в соответствии с заданной в нём логикой (например, подключается к почтовому ящику и скачивает полное письмо или отправляет уведомление о новом письме в мессенджер).

Что передаётся в запросе:

  • Для любых событий:
    • mailbox — адрес почтового ящика.
    • uid — уникальный идентификатор письма.
    • tstamp — временная метка события.
    • event — тип события:
      • new — новое письмо в ящике.
      • create — новое письмо в папке.
      • flags-set — изменение флагов или удаление письма.
    • folder — папка, в которой находится письмо.
    • flags — значения флагов (\\Seen, \\Deleted и т. д.).
  • Для событий нового письма:
    • from — адрес отправителя.
    • to — адрес получателя.
    • subject — тема письма.
    • snippet — превью тела письма (полный текст можно получить только непосредственно через подключение к почтовому ящику).
    • message_id — глобально уникальный идентификатор письма.
  1. Откройте раздел «Webhooks».
  2. Нажмите «Создать вебхук».
  3. Заполните форму и нажмите «Создать»:
    • Название — название вебхука.
    • Почтовые ящики — для каких почтовых ящиков должен срабатывать вебхук.
    • URL — куда будет отправляться запрос (адрес в формате https://example.com/webhook.php).
    • Проверять SSL — если включено, запрос будет отправляться только если у сайта из URL валидный SSL-сертификат.
    • События — при каких условиях будет срабатывать вебхук:
      • Новое письмо в ящике — при поступлении нового письма.
      • Новое письмо в папке — при появлении письма в любой папке (перемещение, создание черновика и т. д.).
        • Учитываются только действия внутри почтового ящика. Поступление нового письма не считается появлением письма в папке.
      • Изменение флагов — при изменении набора флагов (прочитано, помечено и т. д.).
      • Удаление письма — при безвозвратном удалении письма (перемещение в корзину не считается удалением).
  4. Подтвердите владение сайтом из URL — в корневом каталоге этого сайта разместите файл с названием webhook-confirm.txt, в котором будет указан ID вашей учётной записи.

Все созданные вебхуки отображаются в списке в разделе «Webhooks»:

В колонке «Токен» можно скопировать секретный токен. Токен передаётся в заголовке X-Webhook-Token при отправке запроса на адрес из URL. С его помощью скрипт, который обрабатывает запрос, может убедиться, что запрос был отправлен именно с нашего сервера.

В колонке «Последний запрос» выводится код ответа, дата и время отправки последнего запроса.

Кнопка «Лог последних запросов» открывает окно с подробной информацией о 50 последний запросах. В окне выводится информация по каждому запросу: название почтового ящика, сработавшее событие, код ответа, дата и время отправки запроса, а также повторная попытка (если была).

С помощью кнопки ⚙️ («Редактировать») можно изменить настройки существующего вебхука. Настройки такие же, как при создании. Обратите внимание, что при изменении адреса сайта в URL потребуется подтвердить владение им.

Пример простого скрипта, который принимает запрос от вебхука, обрабатывает его и сохраняет полученные данные в виде строки JSON в файл data.log:

<?php

// Укажите тут токен вашего вебхука, чтобы проверять подлинность запросов от сервера
define('SECTRET_TOKEN', 'your_webhook_secret_token_here');

header('Content-Type: application/json; charset=utf-8');

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
	http_response_code(405);
	echo json_encode(['ok' => false, 'error' => 'Method Not Allowed'], JSON_UNESCAPED_UNICODE);
	exit;
}

$headers = getallheaders();
if (!isset($headers['X-Webhook-Token']) || $headers['X-Webhook-Token'] !== SECTRET_TOKEN) {
	http_response_code(401);
	echo json_encode(['ok' => false, 'error' => 'Incorrect webhook token'], JSON_UNESCAPED_UNICODE);
	exit;
}

$raw = file_get_contents('php://input');
if ($raw === false || $raw === '') {
	http_response_code(400);
	echo json_encode(['ok' => false, 'error' => 'Empty body'], JSON_UNESCAPED_UNICODE);
	exit;
}

$data = json_decode($raw, true);
if (json_last_error() !== JSON_ERROR_NONE) {
	http_response_code(400);
	echo json_encode(['ok' => false, 'error' => 'Invalid JSON: ' . json_last_error_msg()], JSON_UNESCAPED_UNICODE);
	exit;
}

$entry = [
	'ts'   => gmdate('c'),
	'ip'   => $_SERVER['REMOTE_ADDR'] ?? null,
	'ua'   => $_SERVER['HTTP_USER_AGENT'] ?? null,
	'data' => $data,
	'webhook_id' => $headers['X-Webhook-Id'] ?? null,
];

// JSONL: одна запись = одна строка
$line = json_encode($entry, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;
$ok = file_put_contents(__DIR__ . '/data.log', $line, FILE_APPEND | LOCK_EX);

if ($ok === false) {
	http_response_code(500);
	echo json_encode(['ok' => false, 'error' => 'Failed to write log'], JSON_UNESCAPED_UNICODE);
	exit;
}

http_response_code(200);
echo json_encode(['ok' => true], JSON_UNESCAPED_UNICODE);
Содержание