Configure Zabbix 7 custom alerting with webhooks and integrations

Intermediate 45 min Apr 25, 2026 50 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Set up advanced Zabbix alerting with custom webhooks for Slack and Microsoft Teams, create notification scripts and templates, and integrate with external systems through API automation.

Prerequisites

  • Zabbix 7 server installed and running
  • Web interface access with admin privileges
  • Slack or Teams workspace for webhook testing

What this solves

Zabbix's default email alerts work for basic monitoring, but production environments need richer notifications and integrations. This tutorial shows you how to configure custom webhooks for Slack and Microsoft Teams, create notification scripts with templates, set up escalation rules, and integrate with external systems using API webhooks.

Step-by-step configuration

Create webhook media type for Slack

Configure Slack webhook integration to send formatted alerts to your team channels.

First, create a Slack webhook URL in your Slack workspace. Go to Your Apps > Incoming Webhooks and create a new webhook for your target channel.

In Zabbix web interface, navigate to Administration > Media types and click Create media type:

Name: Slack
Type: Webhook
Script name: slack
Parameters:
  HTTPProxy: {ALERT.MESSAGE}
  Message: {ALERT.MESSAGE}
  Subject: {ALERT.SUBJECT}
  To: {ALERT.SENDTO}
  URL: https://hooks.slack.com/services/YOUR/WEBHOOK/URL

Add this JavaScript code in the Script field:

try {
    var params = JSON.parse(value),
        req = new HttpRequest(),
        payload = {},
        resp;

    req.addHeader('Content-Type: application/json');

    payload = {
        'channel': params.To,
        'username': 'Zabbix',
        'text': params.Subject,
        'attachments': [{
            'color': params.Subject.indexOf('PROBLEM') !== -1 ? 'danger' : 'good',
            'text': params.Message
        }]
    };

    resp = req.post(params.URL, JSON.stringify(payload));

    if (req.getStatus() !== 200) {
        throw 'Response code: ' + req.getStatus();
    }

    return 'OK';
} catch (error) {
    Zabbix.log(4, 'Slack webhook failed: ' + error);
    throw 'Slack webhook failed: ' + error;
}

Create webhook media type for Microsoft Teams

Set up Microsoft Teams integration for alerts in your Teams channels.

Create an incoming webhook in Microsoft Teams by going to your team channel > Connectors > Incoming Webhook.

In Zabbix, create another media type:

Name: Microsoft Teams
Type: Webhook
Script name: teams
Parameters:
  Message: {ALERT.MESSAGE}
  Subject: {ALERT.SUBJECT}
  URL: https://outlook.office.com/webhook/YOUR/TEAMS/WEBHOOK

Add this JavaScript code for Teams formatting:

try {
    var params = JSON.parse(value),
        req = new HttpRequest(),
        payload = {},
        resp;

    req.addHeader('Content-Type: application/json');

    var color = params.Subject.indexOf('PROBLEM') !== -1 ? 'FF0000' : '00FF00';

    payload = {
        '@type': 'MessageCard',
        '@context': 'https://schema.org/extensions',
        'summary': params.Subject,
        'themeColor': color,
        'sections': [{
            'activityTitle': params.Subject,
            'activityText': params.Message,
            'markdown': true
        }]
    };

    resp = req.post(params.URL, JSON.stringify(payload));

    if (req.getStatus() !== 200) {
        throw 'Response code: ' + req.getStatus();
    }

    return 'OK';
} catch (error) {
    Zabbix.log(4, 'Teams webhook failed: ' + error);
    throw 'Teams webhook failed: ' + error;
}

Create custom notification script

Set up a custom shell script for advanced notification processing and external system integration.

Create the alertscripts directory and custom script:

sudo mkdir -p /usr/lib/zabbix/alertscripts
sudo chown zabbix:zabbix /usr/lib/zabbix/alertscripts
sudo chmod 755 /usr/lib/zabbix/alertscripts

Create a custom notification script:

#!/bin/bash

Custom Zabbix alert script

Parameters: $1=TO, $2=SUBJECT, $3=MESSAGE

TO="$1" SUBJECT="$2" MESSAGE="$3"

Log the alert

echo "$(date): Alert sent to $TO - $SUBJECT" >> /var/log/zabbix/custom-alerts.log

Parse alert severity from subject

if [[ "$SUBJECT" == "DISASTER" ]]; then SEVERITY="critical" COLOR="#FF0000" elif [[ "$SUBJECT" == "HIGH" ]]; then SEVERITY="high" COLOR="#FF8C00" elif [[ "$SUBJECT" == "AVERAGE" ]]; then SEVERITY="medium" COLOR="#FFA500" else SEVERITY="low" COLOR="#00FF00" fi

Send to external API

curl -X POST "https://api.example.com/alerts" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR-API-TOKEN" \ -d "{ \"severity\": \"$SEVERITY\", \"subject\": \"$SUBJECT\", \"message\": \"$MESSAGE\", \"timestamp\": \"$(date -Iseconds)\", \"source\": \"zabbix\" }"

Send SMS for critical alerts

if [[ "$SEVERITY" == "critical" ]]; then curl -X POST "https://api.sms-provider.com/send" \ -d "to=$TO" \ -d "message=CRITICAL: $SUBJECT" \ -d "token=YOUR-SMS-TOKEN" fi exit 0

Make the script executable and set proper ownership:

sudo chmod +x /usr/lib/zabbix/alertscripts/custom-alert.sh
sudo chown zabbix:zabbix /usr/lib/zabbix/alertscripts/custom-alert.sh

Configure Zabbix server for custom scripts

Update Zabbix server configuration to enable custom alertscripts.

Edit the Zabbix server configuration:

# Uncomment and set the alertscripts path
AlertScriptsPath=/usr/lib/zabbix/alertscripts

Enable external scripts

ExternalScripts=/usr/lib/zabbix/externalscripts

Set timeout for scripts

Timeout=30

Create log directory for custom alerts:

sudo mkdir -p /var/log/zabbix
sudo chown zabbix:zabbix /var/log/zabbix
sudo chmod 755 /var/log/zabbix

Restart Zabbix server to apply changes:

sudo systemctl restart zabbix-server
sudo systemctl status zabbix-server

Create script media type

Add the custom script as a media type in Zabbix web interface.

Navigate to Administration > Media types and create a new media type:

Name: Custom Alert Script
Type: Script
Script name: custom-alert.sh
Script parameters:
  {ALERT.SENDTO}
  {ALERT.SUBJECT}
  {ALERT.MESSAGE}

Enable the media type and test it with the Test button.

Configure user media for notifications

Assign notification methods to Zabbix users for different alert types.

Go to Administration > Users, select a user, and click on Media tab. Add media for each notification type:

For Slack:
  Type: Slack
  Send to: #alerts-channel
  When active: 1-7,00:00-24:00
  Use if severity: All selected

For Teams:
  Type: Microsoft Teams
  Send to: teams-webhook
  When active: 1-7,08:00-18:00
  Use if severity: High, Disaster

For Custom Script:
  Type: Custom Alert Script
  Send to: +1234567890
  When active: 1-7,00:00-24:00
  Use if severity: Disaster

Create alert actions with escalation

Set up automated alert actions with escalation rules for different scenarios.

Navigate to Configuration > Actions > Trigger actions and create a new action:

Name: Critical System Alerts

Conditions:
  A: Trigger severity >= High
  B: Host group = Production Servers

Operations:
  Step 1 (0-0): Send message to Slack
  Step 2 (1-3): Send message to Teams (escalation after 5 minutes, repeat 3 times)
  Step 3 (4-0): Send message via Custom Script (escalation after 15 minutes)

Recovery operations:
  Send recovery message to all media types

Update operations:
  Send update message if problem persists > 1 hour

Configure API webhook integration

Create webhook integration with external monitoring systems and ticket systems.

Create an API integration script:

#!/bin/bash

API webhook integration script

TO="$1" SUBJECT="$2" MESSAGE="$3"

Extract host and item from message

HOST=$(echo "$MESSAGE" | grep -oP 'Host: \K[^\n]*' | head -1) ITEM=$(echo "$MESSAGE" | grep -oP 'Item: \K[^\n]*' | head -1) VALUE=$(echo "$MESSAGE" | grep -oP 'Value: \K[^\n]*' | head-1)

Create ticket in external system

if [[ "$SUBJECT" == "PROBLEM" ]]; then TICKET_ID=$(curl -s -X POST "https://api.ticketsystem.com/tickets" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer API-TOKEN" \ -d "{ \"title\": \"$SUBJECT\", \"description\": \"$MESSAGE\", \"priority\": \"high\", \"tags\": [\"monitoring\", \"zabbix\"] }" | jq -r '.id') echo "Created ticket: $TICKET_ID" >> /var/log/zabbix/api-webhooks.log fi

Send to monitoring aggregation service

curl -X POST "https://api.monitoring-hub.com/events" \ -H "Content-Type: application/json" \ -H "X-API-Key: YOUR-API-KEY" \ -d "{ \"source\": \"zabbix\", \"host\": \"$HOST\", \"item\": \"$ITEM\", \"value\": \"$VALUE\", \"subject\": \"$SUBJECT\", \"message\": \"$MESSAGE\", \"timestamp\": $(date +%s) }" exit 0

Make the API webhook script executable:

sudo chmod +x /usr/lib/zabbix/alertscripts/api-webhook.sh
sudo chown zabbix:zabbix /usr/lib/zabbix/alertscripts/api-webhook.sh

Create notification templates

Customize alert message templates for different media types and scenarios.

In each action, configure custom message templates. For Slack notifications:

Subject:
🚨 {TRIGGER.STATUS}: {TRIGGER.NAME}

Message:
Host: {HOST.NAME}
Item: {ITEM.NAME}
Value: {ITEM.LASTVALUE}
Severity: {TRIGGER.SEVERITY}
Time: {EVENT.DATE} {EVENT.TIME}
Age: {EVENT.AGE}

Description: {TRIGGER.DESCRIPTION}

Event ID: {EVENT.ID}

For Teams notifications:

Subject:
{TRIGGER.STATUS}: {HOST.NAME} - {TRIGGER.NAME}

Message:

Alert Details

Host: {HOST.NAME} Trigger: {TRIGGER.NAME} Severity: {TRIGGER.SEVERITY} Status: {TRIGGER.STATUS} Value: {ITEM.LASTVALUE} Time: {EVENT.DATE} {EVENT.TIME} Description: {TRIGGER.DESCRIPTION} Event ID: {EVENT.ID} Host IP: {HOST.IP}

Configure global notification settings

Set up global notification policies and maintenance handling.

Navigate to Administration > General > Other and configure:

Frontend messaging: Enabled
Message timeout: 90 seconds
Max count of elements to show in problems widget: 100

Maintenance settings:
Show suppressed problems: Disabled
Show timeline of events in maintenance: Enabled

Configure notification policies in each action for maintenance periods:

Conditions:
  Maintenance status = Not in maintenance

Pause operations for suppressed problems: Enabled
Notify about cancelled escalations: Enabled

Verify your setup

Test your webhook and script integrations to ensure they work correctly.

# Test custom alert script manually
sudo -u zabbix /usr/lib/zabbix/alertscripts/custom-alert.sh "+1234567890" "TEST: Alert test" "This is a test message"

Check Zabbix server logs for webhook activity

sudo tail -f /var/log/zabbix/zabbix_server.log | grep -i webhook

Check custom alert logs

sudo tail -f /var/log/zabbix/custom-alerts.log

Test webhook media types from Zabbix interface

Go to Administration > Media types > Select media type > Test

Verify alert actions are active

sudo zabbix_server -R config_cache_reload

Advanced webhook configurations

Configure PagerDuty integration

Set up PagerDuty webhook for incident management integration.

Create a PagerDuty media type with this webhook script:

try {
    var params = JSON.parse(value),
        req = new HttpRequest(),
        payload = {},
        resp;

    req.addHeader('Content-Type: application/json');

    var event_action = params.Subject.indexOf('PROBLEM') !== -1 ? 'trigger' : 'resolve';
    
    payload = {
        'routing_key': params.IntegrationKey,
        'event_action': event_action,
        'dedup_key': 'zabbix-' + params.EventID,
        'payload': {
            'summary': params.Subject,
            'source': params.Host,
            'severity': params.Subject.indexOf('DISASTER') !== -1 ? 'critical' : 'warning',
            'custom_details': {
                'message': params.Message,
                'event_id': params.EventID,
                'host': params.Host
            }
        }
    };

    resp = req.post('https://events.pagerduty.com/v2/enqueue', JSON.stringify(payload));

    if (req.getStatus() !== 202) {
        throw 'Response code: ' + req.getStatus();
    }

    return 'OK';
} catch (error) {
    Zabbix.log(4, 'PagerDuty webhook failed: ' + error);
    throw 'PagerDuty webhook failed: ' + error;
}

Create Jira ticket integration

Automatically create Jira tickets for critical alerts using API webhooks.

Create a Jira integration script:

#!/bin/bash

TO="$1"
SUBJECT="$2"
MESSAGE="$3"

Jira API configuration

JIRA_URL="https://yourcompany.atlassian.net" JIRA_USER="monitoring@example.com" JIRA_TOKEN="your-api-token" JIRA_PROJECT="MON"

Create ticket only for PROBLEM events

if [[ "$SUBJECT" == "PROBLEM" ]]; then # Extract event details HOST=$(echo "$MESSAGE" | grep -oP 'Host: \K[^\n]*') SEVERITY=$(echo "$SUBJECT" | grep -oP '(DISASTER|HIGH|AVERAGE|WARNING|INFORMATION)') # Set priority based on severity case "$SEVERITY" in "DISASTER") PRIORITY="Highest" ;; "HIGH") PRIORITY="High" ;; "AVERAGE") PRIORITY="Medium" ;; *) PRIORITY="Low" ;; esac # Create Jira ticket TICKET_RESPONSE=$(curl -s -X POST \ "$JIRA_URL/rest/api/3/issue" \ -H "Content-Type: application/json" \ -u "$JIRA_USER:$JIRA_TOKEN" \ -d "{ \"fields\": { \"project\": {\"key\": \"$JIRA_PROJECT\"}, \"summary\": \"$SUBJECT\", \"description\": \"$MESSAGE\", \"issuetype\": {\"name\": \"Bug\"}, \"priority\": {\"name\": \"$PRIORITY\"}, \"labels\": [\"monitoring\", \"zabbix\", \"$HOST\"] } }") TICKET_KEY=$(echo "$TICKET_RESPONSE" | jq -r '.key') echo "$(date): Created Jira ticket $TICKET_KEY for $SUBJECT" >> /var/log/zabbix/jira-integration.log fi exit 0

Make the script executable and configure as a media type:

sudo chmod +x /usr/lib/zabbix/alertscripts/jira-integration.sh
sudo chown zabbix:zabbix /usr/lib/zabbix/alertscripts/jira-integration.sh

Common issues

SymptomCauseFix
Webhook returns HTTP 400Invalid JSON payload formatValidate JSON syntax and required fields in webhook script
Custom script not executingPermission or path issuesCheck script permissions (755) and AlertScriptsPath in zabbix_server.conf
Slack notifications not formattingIncorrect Slack webhook URLVerify webhook URL and test with curl manually
Escalations not triggeringAction conditions too restrictiveReview action conditions and trigger severity matching
API calls failingAuthentication or timeout issuesCheck API tokens, increase Timeout in zabbix_server.conf
Teams cards not displayingMessageCard format errorsValidate MessageCard schema and test payload

Next steps

Running this in production?

Want this managed for you? Setting this up once is straightforward. Keeping it patched, monitored, backed up and performant across environments is the harder part. See how we run infrastructure like this for European teams.

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle managed devops services for businesses that depend on uptime. From initial setup to ongoing operations.