How to Use Discord Webhook With GitHub Actions for Deploy Notifications
🔍 WiseChecker

How to Use Discord Webhook With GitHub Actions for Deploy Notifications

You want to send a notification to your Discord server every time a GitHub Actions workflow finishes a deploy. A webhook is a simple HTTP callback that posts a message to a Discord channel automatically. Using a Discord webhook with GitHub Actions removes the need to check the GitHub Actions tab manually. This article explains how to create a Discord webhook, set up a GitHub Actions secret, and write a workflow step that sends a deploy notification.

Key Takeaways: Discord Webhook With GitHub Actions

  • Discord Webhook URL: A unique URL that GitHub Actions uses to post messages to a specific channel.
  • GitHub Actions Secret: Stores the webhook URL securely so it is never exposed in your workflow file.
  • Workflow Step with curl: Sends a JSON payload to the webhook URL to create a styled embed message.

ADVERTISEMENT

What Is a Discord Webhook and How Does It Work With GitHub Actions

A Discord webhook is a tool that lets external services push messages into a Discord channel. When you create a webhook in a Discord channel, Discord generates a unique URL. Any application that sends an HTTP POST request to that URL with a properly formatted JSON payload will cause Discord to display a message in that channel. GitHub Actions can send such POST requests using the curl command or a dedicated GitHub Action. The webhook URL itself is sensitive because anyone who has it can post to your channel. That is why you store the URL as a GitHub Actions secret.

Before you start, you need three things: a Discord server where you have the Manage Webhooks permission, a GitHub repository with at least one workflow file, and a terminal or browser to copy the webhook URL. You do not need a bot token or any additional Discord application. The webhook system is built directly into Discord channel settings.

How the Message Payload Works

The JSON payload you send to the webhook URL determines the message appearance. You can include a simple text message or a rich embed with a title, description, color bar, fields, and a timestamp. For deploy notifications, an embed is the standard choice because it shows the workflow name, commit message, author, and status in a clean card layout. The curl command in your GitHub Actions workflow will build this JSON and send it with the Content-Type: application/json header.

Steps to Set Up a Discord Webhook for GitHub Actions Deploy Notifications

Follow these steps to create the webhook, store the URL, and add a notification step to your deploy workflow.

  1. Create a Discord Webhook in Your Server
    Open Discord and go to the server where you want notifications. Right-click the channel name and select Edit Channel. Go to Integrations, then click Webhooks. Click Create Webhook. Give it a name such as Deploy Bot and optionally change the avatar. Click Copy Webhook URL. Save this URL temporarily. Click Save Changes.
  2. Add the Webhook URL as a GitHub Actions Secret
    Go to your GitHub repository. Click Settings > Secrets and variables > Actions. Click New repository secret. Set the name to DISCORD_WEBHOOK. Paste the webhook URL into the Secret field. Click Add secret. The URL is now encrypted and available to your workflows as ${{ secrets.DISCORD_WEBHOOK }}.
  3. Create or Edit Your Deploy Workflow File
    In your repository, navigate to .github/workflows/ and open your deploy workflow YAML file. If you do not have one, create a file such as deploy.yml. The file should already contain steps for building and deploying your application.
  4. Add a Notification Step After the Deploy Step
    Append a new step at the end of the workflow. Use the curl command to send a POST request to the webhook URL. The step should run only when the deploy succeeds. Use the if: success() condition. Below is an example step that sends a simple embed:
    - name: Send Discord notification
      if: success()
      env:
        DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
      run: |
        curl -H "Content-Type: application/json" \
        -X POST \
        -d '{
          "embeds": [{
            "title": "Deploy Successful",
            "description": "The latest commit has been deployed.",
            "color": 3066993,
            "fields": [
              {"name": "Repository", "value": "${{ github.repository }}", "inline": true},
              {"name": "Branch", "value": "${{ github.ref_name }}", "inline": true},
              {"name": "Commit", "value": "${{ github.sha }}", "inline": false}
            ],
            "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
          }]
        }' "$DISCORD_WEBHOOK"

    The color value 3066993 is green. For a failure notification, use 15158332 red.

  5. Test the Workflow
    Push a commit to the branch that triggers your deploy workflow. Go to the Actions tab in GitHub and watch the workflow run. After the deploy step completes, check the Discord channel. You should see the embed message appear within seconds. If the message does not appear, verify the webhook URL secret name and the step condition.

ADVERTISEMENT

Common Mistakes and Limitations

Webhook URL Is Invalid or Missing

If the Discord message never appears, the webhook URL may be wrong or the secret name may be misspelled. Confirm the secret name in GitHub matches exactly what you use in the workflow. Also ensure the webhook was saved in Discord after you copied the URL. You can test the webhook by sending a curl command from your local terminal with the raw URL.

Workflow Step Runs but No Message Appears

The workflow may have run the step but the JSON payload was malformed. Check the workflow run logs for the curl step. If the response is 204 No Content, the request was accepted. A 400 error means the JSON structure is wrong. Common mistakes include missing commas, unescaped quotes, or incorrect embed field names. Use a JSON validator to check the payload string before pasting it into the workflow.

Notifications Only for Successful Deploys

The example above uses if: success() which triggers only when all previous steps succeed. To send a notification on failure, add a second step with if: failure(). You can use the same webhook URL with a different embed color and message text. This gives you separate notifications for success and failure without extra configuration.

Rate Limits and Message Frequency

Discord webhooks have a rate limit of 30 requests per 60 seconds per webhook. For most deploy workflows this limit is never reached. If you run multiple workflows in parallel that all use the same webhook, you may hit the limit. In that case, create separate webhooks for different channels or workflows.

Discord Webhook vs GitHub Actions Slack Notification

Item Discord Webhook GitHub Actions Slack Notification
Setup Create webhook in Discord channel settings, no app registration Requires Slack app installation and OAuth token
Payload format JSON with embed object, simple text, or file upload JSON with Slack Block Kit or legacy attachments
Customization Embed color, fields, author, thumbnail, footer Blocks, buttons, select menus, modals
Rate limit 30 requests per 60 seconds 1 message per second per channel
Cost Free with Discord account Free with Slack free plan, but limited message history

After setting up the webhook, you can expand the notification to include the commit author name, a link to the commit, and the deployment environment. The embed fields support up to 25 fields, so you have room to add build time, version number, or test results. For a production system, consider using a dedicated GitHub Action such as Ilshidur/action-discord that wraps the curl call with additional options. But the plain curl method gives you full control over the payload and avoids dependency on third-party actions.

ADVERTISEMENT