Discord Webhook через Zapier, Make и n8n: автоматизация без кода
Настройка Discord webhook в Zapier, Make и n8n без кода: где ставить HTTP-модуль, готовый JSON с embed, маппинг полей, тестирование и обход rate limit.
На этой странице
- Какой инструмент выбрать
- Один JSON для всех трёх инструментов
- Zapier: действие Webhooks by Zapier
- Куда ставить действие
- Маппинг полей, не ломающий JSON
- Тестирование Zap
- Make: HTTP → Make a request
- Куда ставить модуль
- Маппинг полей
- Тестирование в Make
- n8n: узел Discord или HTTP Request
- Куда ставить узел
- Маппинг через узел Code
- Тестирование в n8n
- Когда ставить n8n на свой сервер
- Rate limit: общие грабли всех трёх инструментов
- Частые ошибки
- FAQ
- Нужен ли Webhooks by Zapier, или хватит приложения Discord в Zapier?
- Можно ли слать embed из n8n без JavaScript?
- Почему Make падает с 429 через раз?
- Можно ли отредактировать или удалить сообщение, отправленное автоматизацией?
- Что дальше
Вебхук — самый дешёвый способ подружить no-code-инструмент с вашим Discord-сервером: без бота, без OAuth и без выдачи прав. Zapier, Make и n8n под капотом делают одно и то же — POST с JSON-телом на https://discord.com/api/webhooks/{id}/{token}, просто прячут его за разными модулями. Ниже — где этот модуль находится в каждом инструменте, точное тело запроса с embed, как безопасно подставлять в него данные триггера и что делать, когда Discord отвечает 429.
Какой инструмент выбрать
- Zapier — самый большой каталог приложений и самая быстрая настройка. Платите за каждый task, а Webhooks by Zapier — premium-приложение, которого на момент написания нет в бесплатном тарифе; перед тем как строить на нём, сверьтесь со страницей тарифов Zapier.
- Make (бывший Integromat) — визуальный холст, дешевле в пересчёте на операцию, HTTP-модуль с сырым JSON, удобная агрегация.
- n8n — open source, ставится на свой сервер, узел Code выполняет настоящий JavaScript. Выбор для больших объёмов, приватных данных, циклов и повторов.
Все три шлют в один и тот же вебхук, так что привязки к инструменту нет.
Один JSON для всех трёх инструментов
Создайте вебхук в Настройки сервера → Интеграции → Вебхуки и скопируйте URL. Любой, у кого он есть, может писать в канал, а единственное лекарство от утечки — удалить вебхук и создать новый.
Сначала отправьте тело один раз через curl — так вы будете уверены, что URL и payload в порядке:
curl -H "Content-Type: application/json" \
-d @- "https://discord.com/api/webhooks/YOUR_ID/YOUR_TOKEN?wait=true" <<'EOF'
{
"username": "Заказы",
"embeds": [{
"title": "Новый заказ #1042",
"url": "https://shop.example.com/orders/1042",
"color": 5793266,
"fields": [
{ "name": "Покупатель", "value": "Анна Смирнова", "inline": true },
{ "name": "Сумма", "value": "12 900 ₽", "inline": true },
{ "name": "Состав", "value": "2 x Худи (M)\n1 x Кепка" }
],
"footer": { "text": "Shopify → Discord" },
"timestamp": "2026-09-17T09:30:00Z"
}]
}
EOF
?wait=true заставляет Discord вернуть созданное сообщение в JSON (с его id) вместо пустого 204. Оставьте параметр: будет тело ответа, которое можно посмотреть, а id позволит потом отредактировать или удалить сообщение.
В любом инструменте color — десятичное число, а не hex-строка, timestamp — ISO 8601, content ограничен 2000 символами, описание embed — 4096, все embed одного сообщения — 6000, и в сообщение помещается до 10 embed. Если удобнее кликать, чем печатать, соберите embed в визуальном конструкторе и экспортируйте JSON; полный список — в статье про лимиты embed.
Zapier: действие Webhooks by Zapier
Куда ставить действие
Триггер (Shopify, Typeform, Gmail, Schedule…) → Action → Webhooks by Zapier → событие Custom Request. Родное приложение Discord в Zapier постит обычный текст и embed не поддерживает.
- Method: POST
- URL: URL вебхука с
?wait=true - Data: JSON-тело из примера выше
- Headers:
Content-Type=application/json
Не берите более простое событие POST: его поле Data — плоские пары ключ/значение, неудобные для embeds, который является массивом объектов. Custom Request отправляет тело как есть.
Маппинг полей, не ломающий JSON
Кликните в поле Data, поставьте курсор внутрь строки и выберите поле триггера из выпадающего списка:
{
"embeds": [
{
"title": "Новый заказ #{{Order Number}}",
"color": 5793266,
"fields": [
{ "name": "Покупатель", "value": "{{Customer Name}}", "inline": true },
{ "name": "Сумма", "value": "{{Total Price}} {{Currency}}", "inline": true }
],
"timestamp": "{{zap_meta_utc_iso}}"
}
]
}
{{zap_meta_utc_iso}} — встроенная в Zapier ISO-метка времени в UTC. Подвох: Zapier вставляет значения как есть, поэтому комментарий с двойной кавычкой или переносом строки ломает JSON, и Discord отвечает 400. Для полей со свободным текстом собирайте тело в шаге Code by Zapier — JSON.stringify экранирует всё сам:
// Code by Zapier (JavaScript). Input Data: name, total, note, url
const embed = {
title: `Новый заказ от ${inputData.name}`.slice(0, 256),
url: inputData.url,
color: 5793266,
description: (inputData.note || '').slice(0, 4096),
fields: [{ name: 'Сумма', value: inputData.total, inline: true }],
timestamp: new Date().toISOString(),
};
return { body: JSON.stringify({ username: 'Заказы', embeds: [embed] }) };
Подставьте выход body из шага Code в поле Data — и больше ничего. Code by Zapier умеет вызывать fetch() и отправить сообщение сам; перед этим сверьтесь с документацией Zapier по лимитам среды выполнения.
Тестирование Zap
Test step на действии Custom Request отправляет настоящий запрос. С ?wait=true в панели ответа будет JSON сообщения; без него пустое тело со статусом 204 — тоже успех. При 400 вы увидите тело ошибки Discord с путём до неправильного поля, например embeds.0.fields.0.value.
Make: HTTP → Make a request
Куда ставить модуль
Добавьте триггер, затем HTTP → Make a request. Собственному приложению Discord в Make нужно подключить бота к вашему серверу; HTTP-модулю нужен только URL.
- URL: URL вебхука с
?wait=true - Method: POST
- Body type: Raw
- Content type: JSON (application/json)
- Request content: JSON-тело
- Parse response: Yes
В расширенных настройках включите Evaluate all states as errors (except for 2xx and 3xx); без этого 400 или 429 проходят как обычный бандл и ошибкой не выглядят.
Маппинг полей
В Request content идёт то же тело, что и в Zapier, только с «пилюлями» вида {{1.customer_name}}. Для метки времени берите {{formatDate(now; YYYY-MM-DDTHH:mm:ssZ; UTC)}}, а не дату, замапленную напрямую из триггера: даты триггеров часто приходят строками в формате источника, а Discord принимает только ISO 8601. Make тоже не экранирует подставленный текст, поэтому для свободного текста идите через JSON → Create JSON: сгенерируйте структуру данных из образца тела, замапьте поля и передайте результат в HTTP-модуль; кавычки и переносы строк он экранирует сам.
Тестирование в Make
Правый клик по HTTP-модулю → Run this module only, либо запустите сценарий один раз. В выходном бандле будут statusCode и, при включённом Parse response, JSON сообщения в data; история выполнений хранит вход и выход каждого модуля, так что упавший запуск покажет, какое поле было неверным.
n8n: узел Discord или HTTP Request
Куда ставить узел
После триггера есть два варианта:
- Узел Discord с credential типа Webhook: URL вставляется один раз в credential (хранится в зашифрованном виде), дальше — Message → Send с полями content, username, avatar и embeds.
- Узел HTTP Request: Method POST, ваш URL, включённый Send Body, Body Content Type JSON, Specify Body: Using JSON. Берите его, когда нужен точный payload.
Маппинг через узел Code
Самый чистый паттерн — узел Code, который собирает payload, и следом HTTP Request. JSON.stringify берёт экранирование на себя, а обрезать под лимиты Discord можно там же:
// Узел Code, режим: Run Once for Each Item
const o = $input.item.json;
return {
json: {
username: 'Заказы',
embeds: [
{
title: `Новый заказ #${o.order_number}`.slice(0, 256),
url: o.order_url,
color: 5793266,
description: (o.note ?? '').slice(0, 4096),
fields: [
{ name: 'Покупатель', value: String(o.customer_name), inline: true },
{ name: 'Сумма', value: `${o.total} ${o.currency}`, inline: true },
],
timestamp: new Date().toISOString(),
},
],
},
};
В узле HTTP Request укажите в JSON-теле {{ JSON.stringify($json) }}. Без узла Code тело можно написать прямо в узле: выражения n8n — это JavaScript, так что {{ $now.toISO() }} даст ISO-метку времени, а {{ $json.note.slice(0, 4096) }} — безопасное описание.
Тестирование в n8n
Test step на узле HTTP Request показывает разобранный ответ; с ?wait=true это объект сообщения с id. В настройках узла включите Retry On Fail с паузой в несколько секунд между попытками — это и есть обработка 429 без дополнительных узлов.
Когда ставить n8n на свой сервер
n8n Cloud хватает на несколько workflow. Self-host нужен, когда:
- Объём — сотни сообщений в день, и цена за выполнение начинает иметь значение; у community-версии лимита на выполнения нет.
- Данные — заказы, тикеты и записи пользователей не должны покидать вашу инфраструктуру.
- Контроль — секреты в переменных окружения (
$env.DISCORD_WEBHOOK_URL), свои npm-пакеты в узлах Code, приватная сеть.
docker run -d --name n8n --restart unless-stopped \
-p 5678:5678 \
-v n8n_data:/home/node/.n8n \
-e N8N_ENCRYPTION_KEY="pick-a-long-random-string" \
-e GENERIC_TIMEZONE="Europe/Moscow" \
docker.n8n.io/n8nio/n8n
Спрячьте n8n за reverse proxy с TLS и бэкапьте том n8n_data: в нём лежат credentials, включая URL вебхука.
Rate limit: общие грабли всех трёх инструментов
Каждый запуск Zap, сценария или workflow — один POST. Для отправки формы это нормально, для массового импорта — проблема. Discord не публикует одной точной цифры для вебхуков, но на практике это около 30 запросов в минуту на вебхук и всплески примерно по 5 запросов за 2 секунды; дальше — 429 с retry_after в теле. Подробности — в статье про rate limit вебхуков Discord.
- Zapier — Digest by Zapier копит записи и отдаёт их одним пакетом по расписанию: десять заказов превращаются в одно сообщение вместо десяти (дайджест — один текстовый блок; если нужен embed на каждый заказ, разберите его в шаге Code). Delay by Zapier разносит запуски по времени; Autoreplay на платных тарифах повторяет упавшие задачи.
- Make — Array aggregator сворачивает N бандлов в один HTTP-вызов, в котором до 10 embed. Для последовательной отправки ставьте Tools → Sleep между итерациями, а на HTTP-модуль повесьте обработчик ошибок Break с повторами, чтобы запрос после 429 уходил заново.
- n8n — HTTP Request → Options → Batching (элементов в пакете, интервал в мс) притормаживает список; Retry On Fail закрывает редкие 429. Для длинных списков — Loop Over Items плюс узел Wait.
Упаковка в embed выгоднее троттлинга: одно сообщение с 10 embed — это один запрос вместо десяти.
Частые ошибки
- 400
The request body contains invalid JSON, код 50109 — кавычка или перенос строки в замапленном поле сломали тело. Маппите через Code (Zapier, n8n) или Create JSON (Make). - 400 по
embeds.0.fields.0.value— замапленное поле оказалось пустым. Давайте необязательным полям запасное значение или убирайте поле, когда значения нет. - 400 по
color— вы передали"#5865F2". Discord ждёт десятичное целое:5793266. - 400 по
username— в переопределении есть «discord» или «clyde» в любом регистре либо больше 80 символов. - 400 по
timestamp— замапленная дата оказалась не в ISO 8601 (поле триггера в формате источника). Используйте{{zap_meta_utc_iso}},formatDate(now; YYYY-MM-DDTHH:mm:ssZ; UTC)или{{ $now.toISO() }}. - 404
Unknown Webhook, код 10015 — URL обрезался при вставке или вебхук удалили. Создайте заново и обновите credential. - Упоминания не пингуют —
<@&roleId>отрисуется, но никто не получит уведомление, покаallowed_mentionsэто не разрешит. См. упоминания в вебхуках Discord.
FAQ
Нужен ли Webhooks by Zapier, или хватит приложения Discord в Zapier?
Приложение Discord в Zapier постит обычный текст без embed. Для embed нужен Webhooks by Zapier → Custom Request с JSON из этой статьи либо шаг Code by Zapier с вызовом fetch().
Можно ли слать embed из n8n без JavaScript?
Да. Узел Discord с credential типа Webhook показывает поля embed, а узел HTTP Request принимает JSON-тело с выражениями {{ }}. Узел Code окупается, только когда нужны экранирование, обрезка или условные поля.
Почему Make падает с 429 через раз?
Триггер возвращает несколько бандлов за запуск, и HTTP-модуль стреляет по разу на бандл — залпом. Соберите бандлы в одно сообщение с несколькими embed либо поставьте модуль Sleep между вызовами и обработчик Break с повторами.
Можно ли отредактировать или удалить сообщение, отправленное автоматизацией?
Да. Отправляйте с ?wait=true, сохраняйте возвращённый id, затем из другого шага делайте PATCH или DELETE на https://discord.com/api/webhooks/{id}/{token}/messages/{message_id}. См. редактирование и удаление сообщений вебхука.
Что дальше
Соберите embed один раз в бесплатном конструкторе Discord Webhook, экспортируйте JSON и вставьте в любой из инструментов. Дальше — сценарии автоматизации с вебхуками Discord за идеями триггеров, Google Sheets → Discord для варианта на таблицах и уведомления через Discord webhook — про то, как держать алерты читаемыми.