Configure a Discord Integration
Send deployment notifications, alerts, and structured messages to Discord.
Use PayloadRelay to send messages to Discord from a service that can make an HTTP request. Configure one Discord webhook target, and send a payload from an endpoint, a script, or an automation workflow.
Purpose#
Use this guide to:
- Create a Discord webhook and add it as a PayloadRelay target.
- Send a payload to a Discord channel.
- Use the Discord formatting and embeds with a message template or a Discord payload.
- Build a deployment notification workflow.
Before you start#
- Make sure that you have the
Manage Webhookspermission on a Discord server. - Create a PayloadRelay endpoint.
- Configure the endpoint to accept
POSTwith theJSONpayload format.
Procedure#
1. Create a Discord webhook#
- In Discord, open the channel where the messages must appear.
- Select
Edit Channelwith the gear icon. SelectIntegrations, thenWebhooks. - Select
New Webhook. - Set the webhook name and avatar. They appear as the message sender.
- Copy the webhook URL, for example,
https://discord.com/api/webhooks/1234/abcdef.
2. Add the Discord target in PayloadRelay#
- Open
Relay targetsand selectAdd target. - Select
Discord webhook. - Paste the Discord webhook URL.
- Give the target a descriptive name, for example,
#deployments Discord. - Save.
3. Attach the target to an endpoint#
- Open the endpoint in
Endpoints. - In
Outputs, add the Discord target. - Save.
PayloadRelay sends a payload that goes to this endpoint to the Discord channel.
4. Send a basic message#
curl -X POST https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID \
-H "Content-Type: application/json" \
-d '{
"event": "deploy",
"version": "3.1.0",
"environment": "production",
"status": "success"
}'By default, PayloadRelay sends this JSON payload as the Discord message content. To send a selected message instead of the complete payload, configure a message template on the Discord destination. You can also send a Discord payload with fields such as content and embeds.
5. Discord markdown formatting#
Discord supports a large subset of Markdown in the message content. Use Markdown in a message template body or in a Discord content field:
| Format | Syntax | Example |
|---|---|---|
| Bold | **text** | **Deployment complete** |
| Italic | *text* | *version 3.1.0* |
| Bold italic | ***text*** | ***critical alert*** |
| Strikethrough | ~~text~~ | ~~deprecated~~ |
| Underline | __text__ | __important__ |
| Inline code | `text` | `production` |
| Code block | ```lang\ncode\n``` | Multi-line code |
| Block quote | > text | > Note: scheduled maintenance |
| Spoiler | ||text|| | ||secret|| |
Example with formatting:
curl -X POST https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID \
-H "Content-Type: application/json" \
-d '{
"content": "**Deployment Complete** 🚀\nVersion `3.1.0` deployed to *production*\n> All health checks passed\n> Zero-downtime migration applied"
}'6. Text-to-speech (TTS)#
A Discord webhook supports text-to-speech. When it is enabled, Discord speaks the message to the users in the channel. If the payload contains a top-level tts field, PayloadRelay sends that field:
curl -X POST https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID \
-H "Content-Type: application/json" \
-d '{
"subject": "Critical alert: database failover triggered",
"tts": true
}'You can also enable TTS on the Discord destination in PayloadRelay. The destination value gives tts when the payload does not contain it. PayloadRelay keeps a top-level tts value in the payload. Use TTS for an urgent alert. Frequent TTS messages can be a problem for the channel members.
7. Deployment notification example#
A complete deployment notification workflow from an automation script:
#!/bin/bash
set -euo pipefail
ENDPOINT="https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID"
VERSION="${1:?Usage: deploy-notify.sh <version>}"
ENVIRONMENT="${2:-production}"
DEPLOYER="${3:-$(whoami)}"
notify() {
local status="$1"
local emoji="$2"
local color="$3"
curl -s -X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-d "$(jq -n \
--arg content "$emoji Deployment $status: v$VERSION" \
--arg version "$VERSION" \
--arg env "$ENVIRONMENT" \
--arg deployer "$DEPLOYER" \
--arg status "$status" \
--arg time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--argjson color "$color" \
'{
content: $content,
embeds: [{
title: "Deployment " + $status,
color: $color,
fields: [
{name: "Version", value: $version, inline: true},
{name: "Environment", value: $env, inline: true},
{name: "Deployed by", value: $deployer, inline: true},
{name: "Timestamp", value: $time, inline: false}
]
}]
}')"
}
# Before deployment
notify "started" "🔄" "3447003"
# Run your deployment
if ./deploy.sh "$VERSION" "$ENVIRONMENT"; then
notify "succeeded" "✅" "3066993"
else
notify "failed" "❌" "15158332"
exit 1
fiUsage:
./deploy-notify.sh 3.1.0 production alice8. Scheduled status report#
Send a daily status report to Discord from a cron job:
#!/bin/bash
ENDPOINT="https://api.payloadrelay.com/relay/YOUR_ENDPOINT_ID"
UPTIME=$(uptime -p 2>/dev/null || uptime | awk '{print $3,$4}')
LOAD=$(uptime | awk -F'load average:' '{print $2}' | xargs)
DISK=$(df -h / | awk 'NR==2 {printf "%s used of %s (%s)", $3, $2, $5}')
curl -s -X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-d "$(jq -n \
--arg content "📊 Daily Status Report - $(hostname)" \
--arg uptime "$UPTIME" \
--arg load "$LOAD" \
--arg disk "$DISK" \
--arg time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
'{
content: $content,
embeds: [{
title: "Daily Status Report",
fields: [
{name: "Uptime", value: $uptime, inline: false},
{name: "Load average", value: $load, inline: false},
{name: "Disk", value: $disk, inline: false},
{name: "Timestamp", value: $time, inline: false}
]
}]
}')"Expected result#
- A message appears in the configured Discord channel.
- A basic payload appears as the Discord message content.
- A message template, and a Discord-native
contentorembedspayload, appear with the channel-native formatting. - A request appears in PayloadRelay
Request activityasCompleted(ACCEPTED). - The Markdown formatting is correct in Discord.
Common issues#
- No message in Discord: make sure that the Discord webhook URL is active and not deleted.
- PayloadRelay rejects the webhook URL: the URL must start with
https://discord.com/api/webhooks/orhttps://discordapp.com/api/webhooks/. - The formatting is wrong: use the Discord Markdown syntax, such as two asterisks for bold, in a message template body or a Discord
contentfield. Do not use the Slackmrkdwnsyntax. - A rate limit: Discord applies rate limits to a webhook. PayloadRelay retries a Discord delivery on a fast schedule, in the limit of the plan. Read PayloadRelay
Request activityfor the delivery failures.