How to Send a Discord Webhook From a GitHub Action
🔍 WiseChecker

How to Send a Discord Webhook From a GitHub Action

Discord webhooks allow automated messages to be posted into a text channel. GitHub Actions can trigger these webhooks to send notifications about repository events. You might want to alert your team about a successful deployment, a failed build, or a new pull request. This article explains how to configure a Discord webhook and integrate it into a GitHub Actions workflow using curl and GitHub Secrets.

The core problem is that GitHub Actions do not have direct access to Discord. You need a way to pass the webhook URL securely and send a properly formatted JSON payload. This guide covers setting up the webhook in Discord, storing the URL as a GitHub Secret, and writing a workflow step that sends the notification.

By the end, you will have a working workflow that posts a custom message to your Discord channel whenever a specific GitHub event occurs. You will also learn how to handle common errors and customize the message content.

Key Takeaways: Sending Discord Webhooks from GitHub Actions

  • Discord Channel > Integrations > Webhooks: Create a webhook and copy its URL from your Discord server settings.
  • GitHub Repository > Settings > Secrets and Variables > Actions: Store the webhook URL as a repository secret named DISCORD_WEBHOOK.
  • curl -H "Content-Type: application/json" -d '{...}' ${{ secrets.DISCORD_WEBHOOK }}: Send the JSON payload from your workflow step.

Understanding Discord Webhooks and GitHub Actions

A Discord webhook is a URL that accepts HTTP POST requests with a JSON body. When you send a request to that URL, Discord posts the message content to the associated text channel. GitHub Actions is a CI/CD platform that runs workflows in response to repository events like pushes, pull requests, or releases.

The combination lets you automate notifications. For example, when a developer pushes code to the main branch, a GitHub Action can build the project and then send a webhook to Discord saying “Build succeeded for commit abc123.” The webhook URL must be kept secret because anyone with that URL can post messages to your channel.

Prerequisites

Before writing the workflow, you need:

  • Administrator or Manage Webhooks permission in the Discord server.
  • A GitHub repository with at least one workflow file (YAML in .github/workflows/).
  • Basic familiarity with YAML syntax and JSON format.

JSON Payload Structure

Discord webhooks accept a JSON object with these common fields:

  • content (string): The main message text, up to 2000 characters.
  • username (string): Overrides the webhook display name.
  • avatar_url (string): Overrides the webhook avatar image.
  • embeds (array): Richer messages with title, description, fields, color, etc.

For simple notifications, the content field is enough. You can include Markdown formatting like bold, italic, and `code`.

Steps to Send a Discord Webhook From a GitHub Action

  1. Create a Discord Webhook
    Open Discord and go to your server. Click the server name at the top-left, then select Server Settings > Integrations > Webhooks. Click New Webhook. Give it a name like “GitHub Notifications” and select the target text channel. Click Copy Webhook URL and save it somewhere secure. You will not be able to see the full URL again after closing the page.
  2. Add the Webhook URL as a GitHub Secret
    Go to your GitHub repository. Click Settings > Secrets and variables > Actions. Click New repository secret. Set the name to DISCORD_WEBHOOK and paste the URL into the value field. Click Add secret. The secret will be masked in logs and cannot be read by unauthorized users.
  3. Create or Edit a Workflow File
    In your repository, navigate to .github/workflows/. Create a new file, for example discord-notify.yml. Use the YAML template below. The workflow triggers on push to the main branch. You can change the trigger to pull_request, release, or any GitHub event.
  4. Write the Workflow Step That Sends the Webhook
    Inside the job, add a step that runs a curl command. Use the secrets.DISCORD_WEBHOOK variable to reference the URL. The JSON payload should include a content field with your message. Example:
    curl -H "Content-Type: application/json" -d '{"content": "Deploy succeeded!"}' ${{ secrets.DISCORD_WEBHOOK }}
  5. Test the Workflow
    Commit and push the workflow file to the main branch. Go to the Actions tab in your repository and watch the workflow run. If the step succeeds, you will see a message in your Discord channel. If it fails, check the workflow logs for error details.

Full Workflow Example

Here is a complete workflow file that sends a notification on every push to the main branch:

name: Discord Notification
on:
  push:
    branches: [ main ]
jobs:
  notify:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Send Discord webhook
        run: |
          curl -H "Content-Type: application/json" \
          -d '{"content": "New push to main branch by ${{ github.actor }}: ${{ github.event.head_commit.message }}"}' \
          ${{ secrets.DISCORD_WEBHOOK }}

This workflow uses github.actor for the username and github.event.head_commit.message for the commit message. You can customize these variables.

Common Mistakes and Limitations

Webhook URL Is Exposed in Logs

If you accidentally print the webhook URL in a workflow step, GitHub masks it as in the logs. However, the URL is still sent as a header. To be safe, never hardcode the URL in the workflow file. Always use secrets.

Payload Size Exceeds Limit

Discord webhooks have a 2000-character limit for the content field. For longer messages, use embeds which allow up to 6000 characters across multiple fields. If you exceed the limit, the webhook returns a 400 Bad Request error.

Rate Limiting

Discord applies rate limits to webhook endpoints. If you send many requests in a short time, you may receive a 429 Too Many Requests response. Add a delay between requests or batch messages. For most CI/CD use cases, one request per workflow run is safe.

Webhook Deleted or Renamed

If someone deletes or renames the webhook in Discord, the URL becomes invalid. The workflow will fail with a 404 Not Found error. Check the Discord server integrations to confirm the webhook still exists.

Discord Webhook Notification Methods: curl vs Official Action

Item curl command Official GitHub Action (e.g., Ilshidur/action-discord)
Setup complexity Minimal: single run step Requires adding a third-party action to your workflow
Flexibility Full control over JSON payload, headers, and error handling Limited to parameters the action exposes
Dependencies None: curl is preinstalled on Ubuntu runners Action may have dependencies or require a specific version
Security Secrets are used directly in the command Action handles secrets through inputs
Maintenance You control the code; no external updates needed Action may become deprecated or break with GitHub changes

You can now send Discord webhooks from a GitHub Action using a simple curl command and a secret. Start with a basic notification and then add embeds for richer messages. For advanced use, consider using an official GitHub Action if you prefer a declarative syntax. Always test your workflow on a non-production branch first to avoid spamming your Discord channel.