Planekeeper is currently in alpha development. Features and APIs may change. Feedback is welcome! Request early access to get started.

Send notifications to Discord

Set up Discord webhook notifications with copy-paste templates for alert events.

This recipe configures Planekeeper to send alert notifications to a Discord channel using webhooks. Discord requires a specific JSON format with a content field for text messages.


Prerequisites

  • A running Planekeeper instance with at least one alert config
  • Admin access to a Discord server

Why Discord needs custom templates

Discord’s webhook API expects a specific JSON structure with a content field for text messages. Planekeeper’s default notification payload does not match this format, so Discord will reject it with a 400 Bad Request error.

You must enable event-specific templates on the notification channel and provide templates that wrap your message in the {"content": "..."} structure Discord requires. The templates in this recipe handle this for you.


Step 1: Create a Discord webhook

  1. Open Discord and go to your target server
  2. Right-click the channel where you want notifications and select Edit Channel
  3. Go to Integrations > Webhooks
  4. Click New Webhook
  5. Give it a name (for example, Planekeeper Alerts)
  6. Click Copy Webhook URL

The URL looks like: https://discord.com/api/webhooks/123456789/abcdefg...


Step 2: Create a notification channel in Planekeeper

  1. Navigate to Notification Channels in the sidebar
  2. Click Create Channel
  3. Fill in the fields:
FieldValue
NameDiscord Alerts
Channel Typewebhook
URLPaste your Discord webhook URL
  1. Check Use Event-Specific Templates
  2. Add the templates from step 3 below
  3. Click Create

Step 3: Add Discord templates

Copy and paste these templates into the corresponding fields.

New alert template

{"content": "**{{.Alert.Severity | upper}} Alert**: {{.Alert.ConfigName}}\n\n**Artifact:** {{.Alert.ArtifactName}}\n**Current:** {{.Alert.DiscoveredVersion}} -> **Latest:** {{.Alert.LatestVersion}}\n**Behind by:** {{.Alert.BehindBy}} ({{.Alert.RuleType}})\n\n[Click to Acknowledge]({{.AcknowledgeURL}})"}

This produces a message like:

CRITICAL Alert: ArgoCD Version Check

Artifact: argoproj.github.io/argo-helm/argo-cd Current: 5.46.0 -> Latest: 6.7.0 Behind by: 8 (minors_behind)

Click to Acknowledge

Acknowledged template

{"content": "{{if .IsAcknowledged}}**Acknowledged**: {{.Alert.ConfigName}} - {{.Alert.ArtifactName}}\nAcknowledged by {{.AcknowledgedBy}}{{else}}**Unacknowledged**: {{.Alert.ConfigName}} - {{.Alert.ArtifactName}}\nAcknowledgment was reset due to a version change{{end}}"}

Resolved template

{"content": "**Resolved**: {{.Alert.ConfigName}} - {{.Alert.ArtifactName}}\nThe version has been updated and no longer triggers this alert."}

Step 4: Test the channel

  1. Go to Notification Channels and find Discord Alerts
  2. Click Test
  3. Check your Discord channel for the test message
  4. If the test fails, verify the webhook URL is correct and the channel still exists
warning

Discord rate limits

Discord limits webhook messages to 30 per minute per channel. If you have many alerts firing simultaneously, some deliveries may be delayed by Planekeeper’s retry logic.


Step 5: Create a notification rule

  1. Navigate to Notification Rules in the sidebar
  2. Click Create Rule
  3. Fill in the fields:
FieldValue
NameAll Alerts to Discord
ChannelSelect Discord Alerts
Severity FilterLeave empty (matches all severities)
Event FilterLeave empty (matches all events)
  1. Click Create

All alert events now route to your Discord channel.

Route only critical alerts

To send only critical alerts to Discord, set the Severity Filter to critical. Create additional notification rules with different channels for other severity levels.


Customizing the format

Minimal template

For a compact notification without the acknowledge link:

{"content": "{{.Alert.Severity | upper}}: {{.Alert.ConfigName}} is {{.Alert.BehindBy}} behind ({{.Alert.DiscoveredVersion}} -> {{.Alert.LatestVersion}})"}

Template with rule details

For more context about why the alert was triggered:

{"content": "**{{.Alert.Severity | upper}}**: {{.Alert.ConfigName}}\nRule: {{.Alert.RuleName}} ({{.Alert.RuleType}})\nRepo: {{.Alert.RepositoryURL}}\nFile: {{.Alert.TargetFile}}\nVersion: {{.Alert.DiscoveredVersion}} -> {{.Alert.LatestVersion}}"}