Вебхуки: заметки из всего, что отправляет HTTP-запросы

У каждого рабочего пространства уже было три входа: приложение, CLI и ИИ-ассистент по MCP. Все три предполагают, что пишет человек или ассистент. Но многое из того, что стоит сохранить, не пишет ни тот, ни другой: упавший деплой, комментарий в Figma, еженедельная выплата, форма, которую кто-то заполнил.

Notez v0.15.0 добавляет четвёртый вход — URL вебхука. Теперь заметку может создать всё, что умеет отправлять HTTP-запросы.

Заметки, созданные вебхуком, в списке заметок Notez; у каждой значок источника WH

Один URL, одна строка curl

Создайте вебхук в разделе Настройки → Интеграции → Вебхуки, и Notez выдаст вам URL. Это вся настройка:

Bash
curl -X POST "https://api.notez.dev/api/webhooks/notes/<your-token>" \
  -H "Content-Type: application/json" \
  -d '{"title": "Deploy failed on main", "content": "## Details\n- commit abc123", "tags": ["alerts"]}'

Заметка появляется с тегами внутри той заметки, которую вы выбрали местом назначения, и в той колонке доски, которую вы указали. Теги, которых ещё нет, создаются автоматически.

Диалог «Новый вебхук»: название, формат данных, заметка назначения, теги по умолчанию, колонка доски и проверка подписи

Отправители, которые не станут учить ваш формат

Аккуратная JSON-структура работает, когда отправитель под вашим контролем. А GitHub, Stripe и Sentry не интересует, какой формат вам нужен: они шлют данные в своём формате, и выбрать вы можете только URL.

Поэтому у вебхука два режима. Формат Notez строго проверяет данные, отклоняет опечатки и принимает заголовок, содержимое, теги и вложения. Любой JSON принимает всё, что пришло, и сохраняет это как отформатированный блок кода. Заголовок берётся из поля title, если оно есть, а если нет — из названия вебхука. Из-за неожиданных полей ничего не отклоняется, ради этого режим и сделан.

Вложения, в том числе те, на которые есть только ссылка

В одном запросе может быть до десяти файлов, и передать их можно тремя способами: как загружаемый файл, в base64 внутри JSON или ссылкой, по которой Notez скачает файл сам. Без третьего способа инструменты автоматизации здесь бесполезны: Zapier передаёт ссылку на файл, а не сами байты.

Скачивать всё, на что указывает URL, — ещё и самый быстрый способ проделать дыру в собственной инфраструктуре. URL вебхука публичный, и без защиты любой мог бы через «скачай эту ссылку» направить серверы Notez на внутренние адреса и прочитать ответ. Перед каждой загрузкой Notez сначала узнаёт IP-адрес, отклоняет частные и внутренние диапазоны и адреса облачных метаданных, проверяет адрес заново после каждого редиректа и подключается только к уже проверенному адресу, так что второй DNS-ответ не подменит его внутренним после проверки. Файлы, которые грузятся слишком медленно, слишком большие или закрыты логином, становятся ссылками в заметке, а не пропадают.

Повторы и заметка, которая не нужна дважды

Отправители повторяют запрос, когда ответ задерживается, а повтор, который создаёт вторую заметку, хуже, чем никакой заметки. Передайте заголовок Idempotency-Key или externalId в теле, и повтор в течение 24 часов вернёт уже созданную заметку. Delivery id от GitHub подхватывается автоматически, так что его повторы безопасны без всякой настройки.

Подпись необязательна, и это намеренно

URL — это и есть учётные данные, а URL утекают: в логи, на скриншоты, в общие конфиги. Если отправитель умеет подписывать запросы, Notez проверит подпись и отклонит всё остальное.

Я сделал проверку необязательной, и это стоит объяснить. Подпись — не замок, который я контролирую: её должен поставить отправитель, а Notez только проверяет. GitHub подписывает. Stripe подписывает. Zapier, «Быстрые команды» и большинство скриптов не умеют. Обязательная подпись превратила бы функцию, которая работает с чем угодно, в функцию для трёх сервисов. Поэтому основа защиты — URL, а подпись — второй слой для отправителей, которые её поддерживают. Вебхуки без подписи отмечены в списке, чтобы этот компромисс оставался на виду, а не забывался.

Два вебхука в рабочем пространстве Notez: без подписи, с предупреждением, и с подписью, с отметкой «С подписью»

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

Заодно: ключи теперь хранятся в виде хешей

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

Теперь они тоже хешируются. На практике это значит, что ключ MCP показывается один раз, когда вы его создаёте, а потом на экране видны только его первые символы. Потеряли ключ — перевыпустите его. CLI свой ключ не показывал и раньше.

Из той же работы выросли ещё две небольшие перемены. Каждый вебхук создаёт заметки от имени того, кто его создал, поэтому теперь, когда человека удаляют из рабочего пространства, его вебхуки удаляются вместе с ним, и ни один URL не переживёт своего владельца. А журнал аудита, который записывает входные данные каждого изменения, теперь скрывает всё, что похоже на учётные данные: он уже собирался сохранять секреты подписи открытым текстом прямо рядом с их зашифрованными копиями.

Куда его направить

  • GitHub — issues, деплои, упавшие workflow, с проверкой подписи.

  • Zapier или Make — шаг в конце любой автоматизации, который кладёт результат туда, где вы его найдёте.

  • Cron и CI — ночные отчёты о бэкапах, заметки к релизам, сводка, которая иначе осталась бы в логе, куда никто не заглядывает.

  • Ваше собственное приложение — обращения в поддержку, регистрации, всё, что стоит хранить рядом с заметками.

У заметок из вебхука есть значок WH, так что ваши собственные записи среди них не потеряются.

Все подробности, лимиты и пошаговая настройка для GitHub — в статье о вебхуках в Центре помощи.

Читайте также