diff --git a/site/assets/docs/images/alerting/slack-custom-degraded.png b/site/assets/docs/images/alerting/slack-custom-degraded.png new file mode 100644 index 000000000..33eb37281 Binary files /dev/null and b/site/assets/docs/images/alerting/slack-custom-degraded.png differ diff --git a/site/assets/docs/images/alerting/slack-custom-failed.png b/site/assets/docs/images/alerting/slack-custom-failed.png new file mode 100644 index 000000000..2d73fc034 Binary files /dev/null and b/site/assets/docs/images/alerting/slack-custom-failed.png differ diff --git a/site/assets/docs/images/alerting/slack-custom-recovered-degraded.png b/site/assets/docs/images/alerting/slack-custom-recovered-degraded.png new file mode 100644 index 000000000..0f6d851ce Binary files /dev/null and b/site/assets/docs/images/alerting/slack-custom-recovered-degraded.png differ diff --git a/site/assets/docs/images/alerting/slack-custom-recovered.png b/site/assets/docs/images/alerting/slack-custom-recovered.png new file mode 100644 index 000000000..9ec4e108f Binary files /dev/null and b/site/assets/docs/images/alerting/slack-custom-recovered.png differ diff --git a/site/content/docs/integrations/slack.md b/site/content/docs/integrations/slack.md index 98d6f3a75..106b9652f 100644 --- a/site/content/docs/integrations/slack.md +++ b/site/content/docs/integrations/slack.md @@ -33,3 +33,205 @@ We provide a lot of information in the initial Slack message including links to From the recovered Slack message, you can see the timestamp as well as a link to the check itself. ![A slack message showing a recovered alert](/docs/images/alerting/slack-recovered-check.png) + + +## Custom Slack Webhook Integration + +For users who need more control over the Slack alert format and content, you can use a **Webhook Alert Channel** in Checkly to send fully customized messages to Slack. + +This approach is ideal when the native Slack integration does not meet your formatting or dynamic content needs. You will be using a Webhook alert channel with a Slack Incoming WebHook URL and a custom payload template. This setup allows you to control Slack message formatting using Slack's [Block Kit](https://api.slack.com/block-kit). + +### Steps + +1. **Create a Slack Webhook** + - [Create an Incoming WebHook integration](https://my.slack.com/services/new/incoming-webhook/) in Slack by selecting a default channel for your alerts. You’ll see a WebHook URL generated by Slack. Copy it. + - Choose the bot name and icon for your alerts. + +2. **Create a Webhook Alert Channel in Checkly** + - Go to [Alert Settings > Add More Channels > Webhook](https://app.checklyhq.com/alerts/settings/channels/new/webhook) + - Fill in the following: + - **Name**: e.g. `Custom Slack Alerts` + - **Method**: `POST` + - **URL**: Paste the Slack Webhook URL + - **Notification events**: Enable recovery, degraded, and failure. SSL expiry optional, but not supported in this template. + - **Body**: See template below + +3. **Customize the Template** + +The following template uses conditional logic (`{{#if}}`) to change the message depending on the alert type: + +``` {title="Body"} +{ + "attachments": [ + { + {{#if (eq ALERT_TYPE "ALERT_FAILURE")}} + "color": "#a30200", + {{/if}} + {{#if (eq ALERT_TYPE "ALERT_RECOVERY")}} + "color": "#2eb886", + {{/if}} + {{#if (eq ALERT_TYPE "ALERT_DEGRADED_RECOVERY")}} + "color": "#2eb886", + {{/if}} + {{#if (eq ALERT_TYPE "ALERT_DEGRADED")}} + "color": "#daa038", + {{/if}} + "blocks": [ + { + "type": "header", + "text": { + "type": "plain_text", + "text": "Check Result Details", + "emoji": true + } + }, + { + "type": "section", + "fields": [ + { + "type": "mrkdwn", + "text": "*Check:*\n" + }, + {{#if GROUP_NAME}} + { + "type": "mrkdwn", + "text": "*Group:*\n{{GROUP_NAME}}" + }, + {{/if}} + { + "type": "mrkdwn", + "text": "*Type:*\n{{CHECK_TYPE}}" + }, + { + "type": "mrkdwn", + "text": "*Started at:*\n{{STARTED_AT}}" + }, + { + "type": "mrkdwn", + "text": "*Run Location:*\n`{{RUN_LOCATION}}`" + }, + { + "type": "mrkdwn", + "text": "*Response Time:*\n{{RESPONSE_TIME}}ms" + } + {{#if API_CHECK_RESPONSE_STATUS_CODE}}, + { + "type": "mrkdwn", + "text": "*Status Code:*\n{{API_CHECK_RESPONSE_STATUS_CODE}} {{API_CHECK_RESPONSE_STATUS_TEXT}}" + } + {{/if}} + ] + }, + {{#if CHECK_ERROR_MESSAGE}} + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "*❌ Error Message:*\n```{{CHECK_ERROR_MESSAGE}}```" + } + }, + {{/if}} + + {{#if (eq ALERT_TYPE "ALERT_RECOVERY")}} + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "✅ *This check has recovered and is now passing successfully.*" + } + }, + {{/if}} + + {{#if (eq ALERT_TYPE "ALERT_DEGRADED_RECOVERY")}} + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "🟡 *This check has recovered from a degraded state.*" + } + }, + {{/if}} + + {{#if (eq ALERT_TYPE "ALERT_DEGRADED")}} + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "⚠️ *This check is running but performance is degraded.*" + } + }, + {{/if}} + + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "🔎 *View full result:*\n<{{RESULT_LINK}}|Click here to view details in Checkly>" + } + }, + { + "type": "actions", + "elements": [ + { + "type": "button", + "text": { + "type": "plain_text", + "text": "Runbook", + "emoji": true + }, + {{#if (eq CHECK_NAME "Check A")}} + "url": "https://example.com/check-a", + {{else if (eq CHECK_NAME "Check B")}} + "url": "https://example.com/check-b", + {{else}} + "url": "https://example.com/default", + {{/if}} + "action_id": "open_link_button" + }, + { + "type": "button", + "text": { + "type": "plain_text", + "text": "OTel Provider", + "emoji": true + }, + "url": "https://example.com", + "action_id": "open_link_button_needs_to_be_unique" + } + ] + }, + { + "type": "context", + "elements": [ + { + "type": "plain_text", + "text": "Tags: {{TAGS}} | UUID: {{CHECK_RESULT_ID}}", + "emoji": false + } + ] + } + ] + } + ] +} +``` + +>[!NOTE] +> Be sure to update or remove the placeholder button links to Runbooks, OTel provider and anything else that is not needed for your use case. + +>[!NOTE] +> Be sure each check mapped in the runbook logic has a corresponding URL. If a match isn’t found, fallback to a default documentation page. + +### Testing the Webhook Limitations +* You cannot use the Test Webhook button in Checkly for this template, as Slack requires valid payload structure and the test payload lacks real check data. +* To test, trigger a real alert by adjusting a check so it fails, degrades, and recovers. + +### Examples of Alert Transitions + +![A customized slack message showing a failed alert](/docs/images/alerting/slack-custom-failed.png) + +![A customized slack message showing a degraded alert](/docs/images/alerting/slack-custom-degraded.png) + +![A customized slack message showing a recovered alert](/docs/images/alerting/slack-custom-recovered.png) + +![A customized slack message showing a recovered alert from degraded state](/docs/images/alerting/slack-custom-recovered-degraded.png)