# Send events to a Discord channel

Relay events into a Discord channel through a Webhooker gateway, with the payload reshaped into the message format Discord expects.

Source: https://docs.webhooker.eu/tutorials/discord/

Discord's incoming webhooks accept a JSON body and post it as a message. That
makes a Discord webhook URL a perfectly ordinary destination — which means any
source you already have can also notify a channel.

## Before you start

- **Manage Webhooks** permission on the target Discord channel.
- A source that is already receiving events.

## 1. Create the Discord webhook

In Discord: channel **Edit Channel → Integrations → Webhooks → New Webhook**.
Name it, pick the channel, and **Copy Webhook URL**:

```
https://discord.com/api/webhooks/<id>/<token>
```

Treat it as a secret — anyone with the URL can post to the channel. To check the
URL works and shape an embed before wiring it up here, use the free
[Discord webhook tester](https://webhooker.eu/tools/discord-webhook-tester).

## 2. Add it as a gateway

In Webhooker, open the source → **Destinations → Add destination → Create new**:

- **Name** — `discord-alerts`.
- **URL** — the Discord webhook URL.
- **Response timeout** — 10 seconds.
- **Sign outbound requests** — leave off. Discord will not verify a signature,
  and the URL is the credential.

## 3. Make the body something Discord renders

Discord renders the `content` field of the JSON body (and `embeds`). A raw
provider payload has no `content`, so add one with a transformation: **Edit
routing** on the row → **Merge body fields**:

```json
{ "content": "New event from {{source.name}} — id {{event.id}}" }
```

The provider's own fields stay in the body; Discord renders `content` and
ignores the rest.

For a per-event summary, template from what the payload actually contains — the
placeholders available are `{{event.id}}`, `{{source.name}}` and
`{{timestamp}}`.

## 4. Filter so the channel stays useful

A channel that gets every event becomes noise. Filter to the ones worth
interrupting people for:

```json
{
  "operator": "or",
  "rules": [
    { "path": "body.type", "op": "eq", "value": "invoice.payment_failed" },
    { "path": "body.type", "op": "contains", "value": "dispute" }
  ]
}
```

## Verify it works

Send a test event from the provider, or resend one from the event log. A message
appears in the channel, and the delivery row shows `succeeded` — Discord answers
`204`, which counts as success.

## Troubleshooting

| Symptom | Cause |
| --- | --- |
| Delivery `failed` with `400` | The body has no `content` or `embeds` that Discord can render. Check the merge rule. |
| Delivery `failed` with `404` | The webhook was deleted in Discord. Create a new one and update the destination URL. |
| Deliveries `exhausted`, `429` in the attempts | Discord rate-limits webhooks. Tighten the filter or give this gateway a longer retry schedule. |
| Messages are unreadable JSON | You are posting the provider payload as `content`. Template a short human sentence instead. |

:::note
Notifications about failing deliveries are better served by
[alerts](/account/alerts/), which have their own Telegram and email channels and
are deduplicated. Use a Discord gateway for business events, not for monitoring
Webhooker itself.
:::
