Integracje · przewodnik

Webhooki Discord — kompletny przewodnik (2026)

Webhook Discord: POST JSON na URL i wiadomość pojawia się na kanale. Bez bota, bez połączenia websocket. Pola embeda, rate limit 30/min, curl/JS/GitHub Actions, pułapki.

10 min czytania · ostatnia aktualizacja: 2026-06-18

Krótka odpowiedź: czym są webhooki Discord

Webhook Discord to URL na który wysyłasz żądanie HTTP POST z JSON-em, a Discord wyświetla wiadomość na wskazanym kanale. Nie potrzeba bota, nie ma trwałego połączenia websocket, jest jednokierunkowy (z systemu zewnętrznego do kanału). Tworzysz go w: ustawienia kanału → Integrations → Webhooks → New Webhook. Limit: 30 wiadomości / minutę per webhook.

Webhook vs bot account — czym się różnią

CechaWebhookBot account
Typ połączeniaBrak (jednorazowy HTTP POST)Websocket gateway (trwałe)
KierunekJednokierunkowy (HTTP → kanał)Dwukierunkowy
Reaguje na komendyNieTak (/komendy, klika przyciski)
Status onlineBrak„Online" w liście członków
Wymaga hostinguNieTak (VPS lub platforma jak FlowCord)
AuthURL = secretToken bota (OAuth2)
Rate limit30/min per webhook50/10s per kanał (globalnie 50/s)
Embed z przyciskamiNie (tylko embed)Tak
Reaguje na zdarzenia (member_join etc.)NieTak

Kiedy używać webhooków

Webhooki błyszczą tam gdzie potrzebujesz prostego dwu-way push z zewnętrznego systemu do kanału Discord, bez pisania bota:

  • CI/CD notifications: GitHub Actions, GitLab CI push webhook na #deploys po każdym build/start.
  • Monitoring: UptimeRobot / BetterStack ping na #alerts gdy endpoint down. Sentry/Rollbar push krytycznych błędów.
  • Formularze: Typeform/Tally wysyła zgłoszenie na #leads.
  • Stripe payments: webhook na #payments po każdym charge.
  • Custom integrations: skrypt Python / N8n / Make.com push danych z dowolnego systemu.

Jeśli potrzebujesz reagowania na wiadomości Discorda (komendy, klika przycisków), webhook nie wystarczy — potrzebujesz bota. Webhooki też nie pozwala na custom logiki (warunki, pętle) — jeśli if status == 'error' then ping @oncall, potrzebujesz bota albo middleware jak N8n.

Jak stworzyć webhook Discord

  1. Na Discordsie: ustawienia kanału (⚙ przy kanale) → Integrations → Webhooks.
  2. Kliknij „New Webhook". Domyślna nazwa „Captain Hook", avatar losowy.
  3. Edytuj nazwę (będzie się podpisywać wiadomościami) i avatar.
  4. Kliknij „Copy Webhook URL". Trzymaj jak hasło.
  5. Test: wyślij curl (przykład poniżej).

Anatomia webhook POST — pola JSON

{
  "content": "Tekst wiadomości (max 2000 znaków)",
  "username": "Nazwa nadpisująca nazwę webhooka",
  "avatar_url": "https://example.com/avatar.png",
  "tts": false,
  "embeds": [
    {
      "title": "Tytuł embeda",
      "description": "Główny tekst embeda (max 4096)",
      "url": "https://link-w-tytule",
      "color": 5736417,
      "timestamp": "2026-06-18T12:00:00.000Z",
      "footer": { "text": "Stopka", "icon_url": "..." },
      "thumbnail": { "url": "https://..." },
      "image": { "url": "https://..." },
      "author": { "name": "Autor", "url": "..." },
      "fields": [
        { "name": "Pole 1", "value": "Wartość", "inline": true },
        { "name": "Pole 2", "value": "Wartość", "inline": false }
      ]
    }
  ],
  "allowed_mentions": {
    "parse": ["users", "roles", "everyone"]
  }
}

Wymagane minimum: {"content":"..."} albo jeden embed. Reszta opcjonalna. color jako integer (nie hex) — wartość RGB złączona w jeden int.

Przykłady kodu

cURL

curl -X POST "https://discord.com/api/webhooks/123/abc..." \
  -H "Content-Type: application/json" \
  -d '{"content":"Deploy zakończony ✅","username":"CI"}'

JavaScript (fetch)

await fetch(process.env.DISCORD_WEBHOOK_URL, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    content: 'Build #' + process.env.BUILD_NUMBER + ' gotowy',
    embeds: [{
      title: 'Szczegóły',
      url: process.env.BUILD_URL,
      color: 0x22C55E, // zielony (parseInt auto)
      fields: [
        { name: 'Branch', value: process.env.BRANCH, inline: true },
        { name: 'Czas', value: process.env.BUILD_TIME + 's', inline: true }
      ]
    }]
  })
});

GitHub Actions YAML

name: Deploy notify
on:
  workflow_dispatch:
jobs:
  notify:
    runs-on: ubuntu-latest
    steps:
      - name: Discord webhook
        env:
          WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK }}
        run: |
          curl -X POST "$WEBHOOK_URL" \
            -H "Content-Type: application/json" \
            -d "{"content":"Deploy zatwierdzony przez ${{ github.actor }}"}"

Rate limits

Discord rate limituje webhooks: 30 wiadomości / minutę per webhook, z burst dozwolonym do 5 wiadomości w pierwszej sekundzie. Powyżej limitu → HTTP 429 z nagłówkiem Retry-After (w sekundach). Implementacja: retry z exponential backoff albo kolejka z opóźnieniem.

Dla CI/CD to nie problem — deploy event raz na jakiś czas. Dla wysokotonażowych powiadomień (1M użytkowników → 1M webhook posts) — użyj bota zamiast webhooka, bot ma wyższe limity (50 msg/10s per kanał globalnie).

Bot + webhook — razem

Webhooki i boty to nie albo-albo. Złożone integracje używają obu:

  • Bot tworzy webhook dynamicznie per kanał (akcja create webhook), zapisuje URL w zmiennej. Każdy kanał ma własny URL.
  • Zewnętrzny system wysyła webhook z powiadomieniem (np. „new order #1234").
  • Bot nasłuchuje na kanale (intent MESSAGE_CREATE), widzi powiadomienie i reaguje — np. tworzy ticket, ping mod, aktualizuje statystyki.

To decouples — system zewnętrzny nie musi znać tokenu bota, pushuje webhook. Bot dostaje dane przez zdarzenie, niesie całą logikę.

Najczęstsze pułapki

  • Webhook URL = secret. Traktuj jak hasło. Nie commit do repo. W GitHub Actions użyj secrets.DISCORD_WEBHOOK. W .env. Jeśli wyciekł: usuń webhook w ustawieniach kanału i stwórz nowy (stary URL jest natychmiast martwy).
  • Embed color jako integer nie jako hex. Discord API wymaga liczby (np. 5736417) a nie stringa ("#5765F2"). W JS: parseInt("5765F2", 16) albo 0x5765f2. W Python: int("5765F2", 16).
  • Rate limit intervals. Po 429 czekaj Retry-After z headera (w sekundach), nie domyślnej wartości. Inaczej ponowny 429.
  • Max 10 embedów / wiadomość. Więcej? Podziel na 2 POST-y z opóźnieniem albo użyj bota z akcją „bulk send".
  • Max 6000 znaków łącznie w embedach + content. Discord tnie po 6000, reszta ląduje w osobnej wiadomości z suffixem „(continued)".
  • Webhook nie „online". Webhook nie pokazuje się w liście członków, nie ma statusu. To po prostu anonimowy sender. Nie nadużywaj do symulacji „bot pisze" — użyj wtedy bota.
  • allowed_mentions domyślnie off. Bez tego pola Discord nie pozwala na wzmianki @everyone / @role przez webhook. Większość kont nie potrzebuje, ale jeśli chcesz pingować rolę — dodaj {"allowed_mentions":{"parse":["roles"]}}.

Webhooki świetnie łączą się z botem FlowCord — bot może zarządzać webhookami dynamiecznie i nasłuchiwać na ich kanałach. Zobacz też artykuł o moderacji automatycznej (bot nasłuchuje na #alerts z webhooka Sentry → auto-reakcja) oraz system ticketów (webhook formularza → nowy ticket). Skoro pytasz o webhooki — sprawdź też porównanie FlowCord vs Discord.js (gdzie webhook możesz obsługiwać z kodu, w FlowCord wizualnie).

Najczęstsze pytania

  • Czy webhook Discord jest bezpieczny?
    Webhook URL działa jak hasło — każdy kto zna URL może wysłać wiadomość. Trzymaj URL w secrets (env vars), nie w repo. Jeśli URL wycieknie: wejdź na ustawienia kanału → Integrations → Webhooks → usuń i stwórz nowy. Discord nie oferuje autoryzacji na webhook URL.
  • Ile wiadomości mogę wysłać przez jeden webhook?
    30 wiadomości na minutę per webhook (burst do 5 w pierwszej sekundzie). Powyżej → HTTP 429 z nagłówkiem Retry-After. W GitHub Actions / CI-CD narzędziach używaj retry z exponential backoff.
  • Czy mogę wysłać embed przez webhook?
    Tak. W JSON body dodaj tablicę embeds (max 10 embedów per wiadomość). Każdy embed ma title, description, fields[], color (jako integer!), thumbnail, image, footer, timestamp. Discord renderuje embed tak samo jak bot-embed.
  • Jaka jest różnica między webhookiem a botem Discord?
    Webhook: jednokierunkowy (POST dari zewnętrznego systemu do kanału), bez połączenia, bez komend, bez „online" statusu. Bot: dwukierunkowy (websocket), reaguje na /komendy, klika przyciski, widzi wiadomości. Webhook jest prosty do powiadomień one-shot. Bot jest pełnoprawną aplikacją.
  • Dlaczego kolor embeda w webhooku jest liczbą a nie hex?
    Discord API definiuje color jako integer (wartość RGB złączona w jeden 24-bit int). W JSON wysyłasz np. 5736417, nie "#5765F2". W FlowCord konwersja jest automatyczna, ale w curl/JS musisz sam: parseInt("5765F2", 16). Częsty bug.
  • Czy mogę połączyć webhook i bota?
    Tak i warto. Bot może dynamicznie tworzyć webhooki (akcja „create webhook" per kanał) i zarządzać nimi. Pattern: zewnętrzny system (CI/CD) wysyła webhook → bot nasłuchuje na webhook channel (intent MESSAGE_CREATE) i reaguje (np. „deploy done" → bot auto-check statystyk na produkcji).

Powiązane artykuły