Discord Notification¶
Posts embed-style or plain-text Discord webhook messages with sensible defaults sourced from the current GitHub run.
Inputs¶
| Input | Required | Default | Description |
|---|---|---|---|
webhook_url |
✅ | — | HTTPS Discord webhook endpoint the action POSTs to; must point to discord.com/discordapp and is always required. |
message_type |
❌ | embed | Controls the payload structure; defaults to 'embed', but set to 'message' to send plain text content. |
title |
❌ | — | Embed title text; ignored when message_type is set to message. |
description |
❌ | — | Embed body/description text appended under the title; ignored for plain messages. |
content |
❌ | — | Plain-text body sent when message_type is message. |
color |
❌ | — | Decimal color value applied to the embed sidebar; Discord falls back to its default gray when omitted. |
fields |
❌ | — | Literal JSON array string inserted into the embed fields collection (for example [{"name":"Field","value":"Value","inline":true}]). |
username |
❌ | — | Overrides the webhook display name; defaults to the triggering GitHub actor when blank. |
avatar_url |
❌ | — | Sets a custom avatar image; defaults to the actor's GitHub avatar URL. |
footer_text |
❌ | — | Footer text rendered at the bottom of embeds; defaults to " |
footer_icon_url |
❌ | — | Optional icon that appears next to the footer text; left unset otherwise. |
image_url |
❌ | — | Displays a full-width image inside the embed when provided. |
thumbnail_url |
❌ | — | Sets the small thumbnail shown in the embed's upper-right corner. |
author_url |
❌ | — | Hyperlink applied to the embed author name (usually the GitHub actor). |
url |
❌ | — | Destination URL applied to the embed title when set. |
Usage¶
Embed notification with dynamic fields (.github/workflows/check-pr.yml):
build-discord-fields-completion:
name: Build Discord Fields
runs-on: ubuntu-latest
needs: [run-integration-tests]
if: always()
outputs:
discord_fields: ${{ steps.discord_fields.outputs.fields }}
steps:
- name: Build Discord Fields
id: discord_fields
run: |
SUMMARY_STATUS="${{ needs['run-integration-tests'].result }}"
# Build JSON fields with readable formatting
FIELDS=$(jq -n \
--arg summary_status "$SUMMARY_STATUS" \
--arg pr_number "${{ github.event.pull_request.number }}" \
--arg pr_url "${{ github.event.pull_request.html_url }}" \
--arg actor "${{ github.actor }}" \
--arg run_url "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
--arg total_tests "${{ needs.run-integration-tests.outputs.total_tests }}" \
--arg passed_tests "${{ needs.run-integration-tests.outputs.passed_tests }}" \
--arg failed_tests "${{ needs.run-integration-tests.outputs.failed_tests }}" \
--arg total_duration "${{ needs.run-integration-tests.outputs.total_duration }}" \
--arg average_duration "${{ needs.run-integration-tests.outputs.average_duration }}" \
'[
{"name": "Step Summary Test", "value": (($summary_status == "success" and "✅ Passed" or "❌ Failed")), "inline": true},
{"name": "Total Tests", "value": $total_tests, "inline": true},
{"name": "Passed Tests", "value": ("✅ " + $passed_tests), "inline": true},
{"name": "Failed Tests", "value": ((($failed_tests == "0") | if . then "✅ " else "❌ " end) + ($failed_tests | tostring)), "inline": true},
{"name": "Total Duration", "value": ($total_duration + "s"), "inline": false},
{"name": "Average Duration", "value": ($average_duration + "s"), "inline": false},
{"name": "PR Details", "value": ("[#" + $pr_number + "](" + $pr_url + ") by @" + $actor), "inline": false},
{"name": "Run Details", "value": ("[View Full Run](" + $run_url + ")"), "inline": false}
]')
# Use delimiter to safely output the multiline JSON
delimiter="$(openssl rand -hex 8)"
{
echo "fields<<${delimiter}"
echo "$FIELDS"
echo "${delimiter}"
} >> "$GITHUB_OUTPUT"
notify-completion:
name: Notify Discord
uses: ./.github/workflows/discord-notify.yml
needs: [build-discord-fields-completion, run-integration-tests]
if: always()
secrets:
webhook_url: ${{ secrets.DISCORD_WEBHOOK_URL }}
with:
message_type: "embed"
title: ${{ needs['run-integration-tests'].result == 'success' && '✅ PR CI Workflow Completed Successfully' || '⚠️ PR CI Workflow Completed with Issues' }}
description: ${{ needs['run-integration-tests'].result == 'success' && 'All validation checks and tests passed successfully. The pull request is ready for review.' || 'The workflow completed but some checks failed. Please review the results and address any issues.' }}
color: ${{ needs['run-integration-tests'].result == 'success' && '3066993' || '16776960' }}
fields: ${{ needs.build-discord-fields-completion.outputs.discord_fields }}
Field payloads
Provide fields as a JSON array of { "name": "...", "value": "...", "inline": bool } objects. Remember to escape quotes or use heredocs when building multi-line JSON.