From 91ac55a11191d09dfe70f2e07e50e93a3f4f84d1 Mon Sep 17 00:00:00 2001 From: cproudlock Date: Tue, 18 Nov 2025 08:38:21 -0500 Subject: [PATCH] Add Zabbix 7.4 MS Teams media type with printer lookup integration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created custom MS Teams webhook for Zabbix 7.4 with the following features: 1. Fixed EVENT.SOURCE error - uses {?EVENT.SOURCE} (optional macro) to prevent "must be 0-4" error during media type testing 2. Printer integration - automatically adds "View Printer" button to alerts: - Captures HOST.IP from Zabbix - Links to printer_lookup.asp?ip={HOST.IP} - Redirects to proper displayprinter.asp page 3. Displays printer IP address in alert facts 4. Two action buttons in Teams messages: - "View in Zabbix" - opens Zabbix event details - "View Printer" - opens ShopDB printer page 5. Color-coded severity levels 6. Support for Problem/Recovery/Update message templates Configuration after import: - Set teams_endpoint to your Teams incoming webhook URL - Set shopdb_url to http://192.168.122.151:8080 (or your ShopDB URL) - Set zabbix_url to your Zabbix server URL 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- zabbix_media_type_teams.json | 146 +++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 zabbix_media_type_teams.json diff --git a/zabbix_media_type_teams.json b/zabbix_media_type_teams.json new file mode 100644 index 0000000..a3e2a5e --- /dev/null +++ b/zabbix_media_type_teams.json @@ -0,0 +1,146 @@ +{ + "zabbix_export": { + "version": "7.4", + "media_types": [ + { + "name": "MS Teams", + "type": "WEBHOOK", + "parameters": [ + { + "name": "alert_message", + "value": "{ALERT.MESSAGE}" + }, + { + "name": "alert_subject", + "value": "{ALERT.SUBJECT}" + }, + { + "name": "event_date", + "value": "{EVENT.DATE}" + }, + { + "name": "event_id", + "value": "{EVENT.ID}" + }, + { + "name": "event_nseverity", + "value": "{EVENT.NSEVERITY}" + }, + { + "name": "event_opdata", + "value": "{EVENT.OPDATA}" + }, + { + "name": "event_recovery_date", + "value": "{EVENT.RECOVERY.DATE}" + }, + { + "name": "event_recovery_time", + "value": "{EVENT.RECOVERY.TIME}" + }, + { + "name": "event_severity", + "value": "{EVENT.SEVERITY}" + }, + { + "name": "event_source", + "value": "{?EVENT.SOURCE}" + }, + { + "name": "event_tags", + "value": "{EVENT.TAGS}" + }, + { + "name": "event_time", + "value": "{EVENT.TIME}" + }, + { + "name": "event_update_action", + "value": "{EVENT.UPDATE.ACTION}" + }, + { + "name": "event_update_date", + "value": "{EVENT.UPDATE.DATE}" + }, + { + "name": "event_update_message", + "value": "{EVENT.UPDATE.MESSAGE}" + }, + { + "name": "event_update_status", + "value": "{EVENT.UPDATE.STATUS}" + }, + { + "name": "event_update_time", + "value": "{EVENT.UPDATE.TIME}" + }, + { + "name": "event_update_user", + "value": "{USER.FULLNAME}" + }, + { + "name": "event_value", + "value": "{EVENT.VALUE}" + }, + { + "name": "host_name", + "value": "{HOST.NAME}" + }, + { + "name": "host_ip", + "value": "{HOST.IP}" + }, + { + "name": "shopdb_url", + "value": "http://192.168.122.151:8080" + }, + { + "name": "teams_endpoint", + "value": "" + }, + { + "name": "trigger_description", + "value": "{TRIGGER.DESCRIPTION}" + }, + { + "name": "trigger_id", + "value": "{TRIGGER.ID}" + }, + { + "name": "use_default_message", + "value": "false" + }, + { + "name": "zabbix_url", + "value": "{$ZABBIX.URL}" + } + ], + "script": "var Teams = {\n severity_colors: [\n '#97AAB3', // Not classified\n '#7499FF', // Information\n '#FFC859', // Warning\n '#FFA059', // Average\n '#E97659', // High\n '#E45959' // Disaster\n ],\n\n message: null,\n teams_endpoint: null,\n\n sendMessage: function() {\n var params = {\n themeColor: (Teams.message.event_nseverity !== undefined && Teams.message.event_nseverity !== '')\n ? Teams.severity_colors[Teams.message.event_nseverity]\n : Teams.severity_colors[0],\n title: Teams.message.alert_subject,\n text: Teams.message.alert_message.replace(/\\n/g, '\\n\\n'),\n sections: [\n {\n facts: Teams.buildFacts()\n }\n ]\n };\n\n if (Teams.message.trigger_id !== undefined && Teams.message.trigger_id !== '') {\n params.potentialAction = [\n {\n '@type': 'OpenUri',\n name: 'View in Zabbix',\n targets: [\n {\n os: 'default',\n uri: Teams.message.zabbix_url +\n '/tr_events.php?triggerid=' + Teams.message.trigger_id +\n '&eventid=' + Teams.message.event_id\n }\n ]\n }\n ];\n\n // Add View Printer button if host IP is available\n if (Teams.message.host_ip !== undefined && Teams.message.host_ip !== '' && \n Teams.message.shopdb_url !== undefined && Teams.message.shopdb_url !== '') {\n params.potentialAction.push({\n '@type': 'OpenUri',\n name: 'View Printer',\n targets: [\n {\n os: 'default',\n uri: Teams.message.shopdb_url + '/printer_lookup.asp?ip=' + Teams.message.host_ip\n }\n ]\n });\n }\n }\n\n var request = new HttpRequest();\n request.addHeader('Content-Type: application/json');\n var response = request.post(Teams.teams_endpoint, JSON.stringify(params));\n\n Zabbix.log(4, '[MS Teams Webhook] Received response with status code ' + request.getStatus() + '. Body: ' + response);\n\n if (request.getStatus() !== 200) {\n throw 'Request failed with status code ' + request.getStatus() + ': ' + response;\n }\n },\n\n buildFacts: function() {\n var facts = [];\n\n if (Teams.message.host_name !== undefined && Teams.message.host_name !== '') {\n facts.push({name: 'Host', value: Teams.message.host_name});\n }\n\n if (Teams.message.host_ip !== undefined && Teams.message.host_ip !== '') {\n facts.push({name: 'IP Address', value: Teams.message.host_ip});\n }\n\n if (Teams.message.event_severity !== undefined && Teams.message.event_severity !== '') {\n facts.push({name: 'Severity', value: Teams.message.event_severity});\n }\n\n if (Teams.message.event_opdata !== undefined && Teams.message.event_opdata !== '') {\n facts.push({name: 'Operational data', value: Teams.message.event_opdata});\n }\n\n if (Teams.message.trigger_description !== undefined && Teams.message.trigger_description !== '') {\n facts.push({name: 'Description', value: Teams.message.trigger_description});\n }\n\n if (Teams.message.event_tags !== undefined && Teams.message.event_tags !== '') {\n facts.push({name: 'Tags', value: Teams.message.event_tags});\n }\n\n if (Teams.message.event_value === '1') {\n facts.push({name: 'Event time', value: Teams.message.event_date + ' ' + Teams.message.event_time});\n }\n else if (Teams.message.event_recovery_date !== undefined && Teams.message.event_recovery_date !== '') {\n facts.push({name: 'Recovery time', value: Teams.message.event_recovery_date + ' ' + Teams.message.event_recovery_time});\n }\n\n if (Teams.message.event_update_status === '1') {\n facts.push({name: 'Update action', value: Teams.message.event_update_action});\n facts.push({name: 'Updated by', value: Teams.message.event_update_user});\n facts.push({name: 'Update time', value: Teams.message.event_update_date + ' ' + Teams.message.event_update_time});\n facts.push({name: 'Update message', value: Teams.message.event_update_message});\n }\n\n return facts;\n }\n};\n\ntry {\n var params = JSON.parse(value);\n\n if (typeof params.teams_endpoint !== 'string' || params.teams_endpoint.trim() === '') {\n throw 'Cannot get teams_endpoint';\n }\n\n Teams.teams_endpoint = params.teams_endpoint;\n\n if (params.use_default_message !== 'false') {\n params.alert_message = JSON.parse(params.alert_message);\n params.alert_subject = params.alert_subject || 'Unknown';\n }\n\n Teams.message = params;\n Teams.sendMessage();\n\n return 'OK';\n}\ncatch (error) {\n Zabbix.log(3, '[MS Teams Webhook] Notification failed: ' + error);\n throw 'Sending failed: ' + error + '.';\n}\n", + "process_tags": "YES", + "show_event_menu": "YES", + "event_menu_url": "{EVENT.TAGS.__zbx_teams_endpoint}", + "event_menu_name": "Open in MS Teams", + "message_templates": [ + { + "event_source": "TRIGGERS", + "operation_mode": "PROBLEM", + "subject": "Problem: {EVENT.NAME}", + "message": "Problem started at {EVENT.TIME} on {EVENT.DATE}\nProblem name: {EVENT.NAME}\nHost: {HOST.NAME}\nSeverity: {EVENT.SEVERITY}\nOperational data: {EVENT.OPDATA}\nOriginal problem ID: {EVENT.ID}\n{TRIGGER.URL}" + }, + { + "event_source": "TRIGGERS", + "operation_mode": "RECOVERY", + "subject": "Resolved: {EVENT.NAME}", + "message": "Problem has been resolved at {EVENT.RECOVERY.TIME} on {EVENT.RECOVERY.DATE}\nProblem name: {EVENT.NAME}\nProblem duration: {EVENT.DURATION}\nHost: {HOST.NAME}\nSeverity: {EVENT.SEVERITY}\nOriginal problem ID: {EVENT.ID}\n{TRIGGER.URL}" + }, + { + "event_source": "TRIGGERS", + "operation_mode": "UPDATE", + "subject": "Updated problem: {EVENT.NAME}", + "message": "{USER.FULLNAME} {EVENT.UPDATE.ACTION} problem at {EVENT.UPDATE.DATE} {EVENT.UPDATE.TIME}.\n{EVENT.UPDATE.MESSAGE}\n\nCurrent problem status: {EVENT.STATUS}\nAge: {EVENT.AGE}\nAcknowledged: {EVENT.ACK.STATUS}" + } + ] + } + ] + } +}