zabbix_export:
  version: '7.0'
  media_types:
    - name: PagerDuty
      type: WEBHOOK
      parameters:
        - name: alert_message
          value: '{ALERT.MESSAGE}'
        - name: eventack
          value: '{EVENT.ACK.STATUS}'
        - name: eventdate
          value: '{EVENT.DATE}'
        - name: eventid
          value: '{EVENT.ID}'
        - name: eventname
          value: '{ALERT.SUBJECT}'
        - name: eventtags
          value: '{EVENT.TAGS}'
        - name: eventtime
          value: '{EVENT.TIME}'
        - name: eventupdate
          value: '{EVENT.UPDATE.STATUS}'
        - name: eventvalue
          value: '{EVENT.VALUE}'
        - name: event_source
          value: '{EVENT.SOURCE}'
        - name: hostip
          value: '{HOST.IP}'
        - name: hostname
          value: '{HOST.NAME}'
        - name: severity
          value: '{EVENT.NSEVERITY}'
        - name: token
          value: '<put your key>'
        - name: triggerdesc
          value: '{TRIGGER.DESCRIPTION}'
        - name: triggerid
          value: '{TRIGGER.ID}'
        - name: triggeropdata
          value: '{EVENT.OPDATA}'
        - name: url
          value: '{$ZABBIX.URL}'
      status: DISABLED
      script: |
        try {
        
            var params = JSON.parse(value),
                req = new HttpRequest(),
                fields = {},
                resp = '';
        
            // Correspondence between the PagerDuty and Zabbix severity level
            var severityMapping = [
                'info',    // Not classified
                'info',    // Information
                'warning', // Warning
                'warning', // Average
                'error',   // High
                'critical' // Disaster
            ];
        
            if (!severityMapping[params.severity]) {
                params.severity = '0';
            }
        
            if (typeof params.HTTPProxy === 'string' && params.HTTPProxy.trim() !== '') {
                req.setProxy(params.HTTPProxy);
            }
        
            if (isNaN(parseInt(params.eventid)) || params.eventid < 1) {
                throw 'incorrect value for variable "eventid". The value must be a positive number.';
            }
            if (params.eventname.length < 1) {
                throw 'incorrect value for variable "eventname". The value must be a non-empty string.';
            }
            if (isNaN(parseInt(params.severity)) || (params.severity < 0 && params.severity > 5)) {
                throw 'incorrect value for variable "severity". The value must be a number 0..5.';
            }
        
            if ([0, 1, 2, 3].indexOf(parseInt(params.event_source)) === -1) {
                throw 'Incorrect "event_source" parameter given: "' + params.event_source + '".\nMust be 0-3.';
            }
            // Check {EVENT.VALUE} for trigger-based and internal events.
            if (params.eventvalue !== '0' && params.eventvalue !== '1'
                && (params.event_source === '0' || params.event_source === '3')) {
                throw 'Incorrect "eventvalue" parameter given: "' + params.eventvalue + '".\nMust be 0 or 1.';
            }
        
            if (params.event_source === '0') {
                if (params.hostname.length < 1) {
                    throw 'incorrect value for variable "hostname". The value must be a non-empty string.';
                }
                if (isNaN(parseInt(params.triggerid)) || params.triggerid < 1) {
                    throw 'incorrect value for variable "triggerid". The value must be a positive number.';
                }
                if (params.eventack != 'Yes' && params.eventack != 'No') {
                    throw 'incorrect value for variable "eventack". The value must be Yes or No.';
                }
                if (isNaN(parseInt(params.eventupdate)) || (params.eventupdate < 0 || params.eventupdate > 1)) {
                    throw 'incorrect value for variable "eventupdate". The value must be 0 or 1.';
                }
            }
        
        
        
            req.addHeader('Content-Type: application/json');
        
            fields.routing_key = params.token;
            fields.dedup_key = params.eventid;
        
            if (((params.eventvalue == 1) && (params.eventupdate == 0)) || params.event_source !== '0') {
                fields.event_action = 'trigger';
                fields.payload = {
                    summary: params.eventname,
                    source: (params.event_source === '1') ? 'Discovery' : params.hostname + ' : ' + params.hostip,
                    severity: severityMapping[params.severity],
                };
                
                if (params.event_source === '0') {
                    fields.payload.custom_details = {
                        'Event date': params.eventdate,
                        'Event time': params.eventtime,
                        'Trigger description': params.triggerdesc,
                        'Trigger opdata': params.triggeropdata,
                        'Event tags': params.eventtags,
                        'Event host': params.hostname,
                        'Event host ip': params.hostip
                    };
                    fields.links = [{
                        href: params.url + '/tr_events.php?triggerid=' + params.triggerid + '&eventid=' + params.eventid,
                        text: 'Event link'
                    }];
                }
                else {
                    fields.payload.custom_details = {
                        'Alert message': params.alert_message
                    };
                }
        
                fields.client = 'Zabbix';
                fields.client_url = params.url;
            }
            else if ((params.eventvalue == 1) && (params.eventupdate == 1) && (params.eventack == 'Yes'))
                fields.event_action = 'acknowledge';
            else if (params.eventvalue == 0) {
                fields.event_action = 'resolve';
                fields.payload = {
                    summary: params.eventname,
                    source: (params.event_source === '1') ? 'Discovery' : params.hostname + ' : ' + params.hostip,
                    severity: severityMapping[params.severity],
                };
        
                if (params.event_source === '0') {
                    fields.payload.custom_details = {
                        'Event date': params.eventdate,
                        'Event time': params.eventtime,
                        'Trigger description': params.triggerdesc,
                        'Trigger opdata': params.triggeropdata,
                        'Event tags': params.eventtags,
                        'Event host': params.hostname,
                        'Event host ip': params.hostip
                    };
                }
            }
            else
                throw 'incorrect values. Update message without ack will not be sent.';
        
            Zabbix.log(4, '[PagerDuty Webhook] Sending request:' + JSON.stringify(fields));
            resp = req.post('https://events.pagerduty.com/v2/enqueue',
                JSON.stringify(fields)
            );
            Zabbix.log(4, '[PagerDuty Webhook] Receiving response:' + resp);
        
            try {
                resp = JSON.parse(resp);
            }
            catch (error) {
                throw 'incorrect response. PagerDuty returned a non-JSON object.';
            }
        
            if (req.getStatus() != 202) {
                if (typeof resp === 'object' && typeof resp.errors === 'object' && typeof resp.errors[0] === 'string') {
                    throw resp.errors[0];
                }
                else {
                    throw 'Unknown error.';
                }
            }
        
            if (resp.status != 'success') {
                throw 'Unknown error.';
            }
        
            return 'OK';
        }
        catch (error) {
            Zabbix.log(3, '[PagerDuty Webhook] Notification failed : ' + error);
            throw 'PagerDuty notification failed : ' + error;
        }
      description: |
        Please refer to https://v2.developer.pagerduty.com/docs/send-an-event-events-api-v2 and https://www.zabbix.com/documentation/7.0/manual/config/notifications/media/webhook#example_scripts.
          
        Set global macro {$ZABBIX.URL} with your Zabbix server URL.
        Add a dedicated user with the media type "PagerDuty" and place the integration key in the "token" parameter to integrate into the service.
      message_templates:
        - event_source: TRIGGERS
          operation_mode: PROBLEM
          subject: 'Problem: {EVENT.NAME}'
          message: |
            Problem started at {EVENT.TIME} on {EVENT.DATE}
            Problem name: {EVENT.NAME}
            Host: {HOST.NAME}
            Severity: {EVENT.SEVERITY}
            Operational data: {EVENT.OPDATA}
            Original problem ID: {EVENT.ID}
            {TRIGGER.URL}
        - event_source: TRIGGERS
          operation_mode: RECOVERY
          subject: 'Resolved in {EVENT.DURATION}: {EVENT.NAME}'
          message: |
            Problem has been resolved at {EVENT.RECOVERY.TIME} on {EVENT.RECOVERY.DATE}
            Problem name: {EVENT.NAME}
            Problem duration: {EVENT.DURATION}
            Host: {HOST.NAME}
            Severity: {EVENT.SEVERITY}
            Original problem ID: {EVENT.ID}
            {TRIGGER.URL}
        - event_source: TRIGGERS
          operation_mode: UPDATE
          subject: 'Updated problem in {EVENT.AGE}: {EVENT.NAME}'
          message: |
            {USER.FULLNAME} {EVENT.UPDATE.ACTION} problem at {EVENT.UPDATE.DATE} {EVENT.UPDATE.TIME}.
            {EVENT.UPDATE.MESSAGE}
            
            Current problem status is {EVENT.STATUS}, age is {EVENT.AGE}, acknowledged: {EVENT.ACK.STATUS}.
        - event_source: DISCOVERY
          operation_mode: PROBLEM
          subject: 'Discovery: {DISCOVERY.DEVICE.STATUS} {DISCOVERY.DEVICE.IPADDRESS}'
          message: |
            Discovery rule: {DISCOVERY.RULE.NAME}
            
            Device IP: {DISCOVERY.DEVICE.IPADDRESS}
            Device DNS: {DISCOVERY.DEVICE.DNS}
            Device status: {DISCOVERY.DEVICE.STATUS}
            Device uptime: {DISCOVERY.DEVICE.UPTIME}
            
            Device service name: {DISCOVERY.SERVICE.NAME}
            Device service port: {DISCOVERY.SERVICE.PORT}
            Device service status: {DISCOVERY.SERVICE.STATUS}
            Device service uptime: {DISCOVERY.SERVICE.UPTIME}
        - event_source: AUTOREGISTRATION
          operation_mode: PROBLEM
          subject: 'Autoregistration: {HOST.HOST}'
          message: |
            Host name: {HOST.HOST}
            Host IP: {HOST.IP}
            Agent port: {HOST.PORT}