zabbix_export: version: '7.0' media_types: - name: Express.ms type: WEBHOOK parameters: - name: event_source value: '{EVENT.SOURCE}' - name: event_update_status value: '{EVENT.UPDATE.STATUS}' - name: event_value value: '{EVENT.VALUE}' - name: express_message value: '{ALERT.MESSAGE}' - name: express_send_to value: '{ALERT.SENDTO}' - name: express_tags value: '{EVENT.TAGSJSON}' - name: express_token value: '' - name: express_url value: '' script: | var Express = { params: [], setParams: function (params) { if (typeof params !== 'object') { return; } Express.params = params; if (typeof Express.params.url === 'string' && !Express.params.url.endsWith('/')) { Express.params.url += '/'; } }, setProxy: function (HTTPProxy) { Express.HTTPProxy = HTTPProxy; }, request: function (query, data) { var response, url = Express.params.url + query, request = new HttpRequest(); request.addHeader('Content-Type: application/json'); request.addHeader('Authorization: Bearer ' + Express.params.token); if (typeof Express.HTTPProxy !== 'undefined' && Express.HTTPProxy !== '') { request.setProxy(Express.HTTPProxy); } if (typeof data !== 'undefined') { data = JSON.stringify(data); } Zabbix.log(4, '[ Express Webhook ] Sending request: ' + url + ((typeof data === 'string') ? ('\n' + data) : '')); response = request.post(url, data); Zabbix.log(4, '[ Express Webhook ] Received response with status code ' + request.getStatus() + '\n' + response); if (response !== null) { try { response = JSON.parse(response); } catch (error) { Zabbix.log(4, '[ Express Webhook ] Failed to parse response received from Express'); response = {}; } } if (response.status !== 'ok') { var message = 'Request failed with status code ' + request.getStatus(); if (typeof response.reason !== 'undefined') { message += ': ' + JSON.stringify(response.reason); } throw message + '. Check debug log for more information.'; } return response.result; }, postMessage: function (is_problem) { var data, url, result = {tags: {}}, response; if (is_problem) { data = { group_chat_id: Express.params.send_to, notification: { status: 'ok', body: Express.params.message } }; url = 'api/v4/botx/notifications/direct'; } else { data = { reply: { status: 'ok', body: Express.params.message } }; url = 'api/v3/botx/events/reply_event'; try { var tags = JSON.parse(Express.params.tags); } catch (error) { throw 'Value of "express_tags" is not JSON. Value: ' + Express.params.tags + '.'; } tags.forEach(function(tag) { if (tag.tag === '__zbx_ex_sync_id_' + Express.params.send_to) { data.source_sync_id = tag.value; } }); if (!data.source_sync_id) { throw 'Cannot update data. sync_id for the provided sender is unknown.'; } } response = Express.request(url, data); if (is_problem && response.sync_id) { result.tags['__zbx_ex_sync_id_' + Express.params.send_to] = response.sync_id; return JSON.stringify(result); } else { return 'OK'; } } }; try { var params = JSON.parse(value), express = {}, required_params = [ 'express_url', 'express_send_to', 'express_message', 'express_tags', 'express_token', 'event_source', 'event_value', 'event_update_status' ]; Object.keys(params) .forEach(function (key) { if (key.startsWith('express_')) { express[key.substring(8)] = params[key]; } if (required_params.indexOf(key) !== -1 && (params[key].trim() === '' || params[key] === '{ALERT.SENDTO}')) { throw 'Parameter "' + key + '" can\'t be empty.'; } }); if ([0, 1, 2, 3].indexOf(parseInt(params.event_source)) === -1) { throw 'Incorrect "event_source" parameter given: ' + params.event_source + '\nMust be 0-3.'; } // Forcing event_value and event_update_status for non trigger-based events. if (params.event_source !== '0' ) { params.event_value = '1'; params.event_update_status = '0'; } if (params.event_value !== '0' && params.event_value !== '1') { throw 'Incorrect "event_value" parameter given: ' + params.event_value + '\nMust be 0 or 1.'; } // Check {EVENT.UPDATE.STATUS} only for trigger-based events. if (params.event_update_status !== '0' && params.event_update_status !== '1' && params.event_source === '0') { throw 'Incorrect "event_update_status" parameter given: ' + params.event_update_status + '\nMust be 0 or 1.'; } Express.setParams(express); Express.setProxy(params.HTTPProxy); return Express.postMessage(params.event_value === '1' && params.event_update_status === '0'); } catch (error) { Zabbix.log(3, '[ Express Webhook ] ERROR: ' + error); throw 'Sending failed: ' + error; } process_tags: 'YES' message_templates: - event_source: TRIGGERS operation_mode: PROBLEM subject: '[{EVENT.STATUS}] {EVENT.NAME}' message: | [{EVENT.STATUS}] {EVENT.NAME} Started at {EVENT.TIME} on {EVENT.DATE} Host: {HOST.NAME} Severity: {EVENT.SEVERITY} Operational data: {EVENT.OPDATA} Event info: {$ZABBIX.URL}/tr_events.php?triggerid={TRIGGER.ID}&eventid={EVENT.ID} - event_source: TRIGGERS operation_mode: RECOVERY subject: 'Resolved in {EVENT.DURATION}: {EVENT.NAME}' message: | [{EVENT.STATUS}] {EVENT.NAME} Resolved in {EVENT.DURATION} at {EVENT.RECOVERY.TIME} on {EVENT.RECOVERY.DATE} Host: {HOST.NAME} Severity: {EVENT.SEVERITY} Event info: {$ZABBIX.URL}/tr_events.php?triggerid={TRIGGER.ID}&eventid={EVENT.ID} - event_source: TRIGGERS operation_mode: UPDATE subject: '[{EVENT.STATUS}] {EVENT.NAME}' message: | [{EVENT.STATUS}] {EVENT.NAME} {USER.FULLNAME} {EVENT.UPDATE.ACTION} problem at {EVENT.UPDATE.DATE} {EVENT.UPDATE.TIME}. {EVENT.UPDATE.MESSAGE} - event_source: DISCOVERY operation_mode: PROBLEM subject: 'Discovery: {DISCOVERY.DEVICE.STATUS} {DISCOVERY.DEVICE.IPADDRESS}' message: | Discovery: {DISCOVERY.DEVICE.STATUS} {DISCOVERY.DEVICE.IPADDRESS} 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: | Autoregistration: {HOST.HOST} Host IP: {HOST.IP} Agent port: {HOST.PORT}