Last active
February 21, 2025 17:54
-
-
Save spy86/1a084c5670b0029b10310ef307ff5543 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
zabbix_export: | |
version: '6.4' | |
media_types: | |
- | |
name: 'MS Teams Workflows' | |
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_status | |
value: '{EVENT.STATUS}' | |
- | |
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_ip | |
value: '{HOST.IP}' | |
- | |
name: host_name | |
value: '{HOST.NAME}' | |
- | |
name: teams_endpoint | |
value: '<PLACE WEBHOOK URL HERE>' | |
- | |
name: trigger_description | |
value: '{TRIGGER.DESCRIPTION}' | |
- | |
name: trigger_id | |
value: '{TRIGGER.ID}' | |
- | |
name: use_default_message | |
value: 'false' | |
- | |
name: zabbix_url | |
value: '{$ZABBIX.URL}' | |
status: DISABLED | |
script: | | |
var SEVERITY_COLORS = [ | |
'emphasis', // Not classified. | |
'accent', // Information. | |
'warning', // Warning. | |
'warning', // Average. | |
'attention', // High. | |
'attention', // Disaster. | |
'good', // Resolved. | |
'default' // Default. | |
]; | |
try { | |
var params = JSON.parse(value); | |
if (typeof params.teams_endpoint !== 'string' || params.teams_endpoint.trim() === '') { | |
throw 'Cannot get teams_endpoint'; | |
} | |
else if (!params.teams_endpoint.startsWith('http')) { | |
throw 'Invalid MS Teams webhook URL: ' + params.teams_endpoint; | |
} | |
params.zabbix_url = (params.zabbix_url.endsWith('/')) | |
? params.zabbix_url.slice(0, -1) : params.zabbix_url; | |
if ([0, 1, 2, 3, 4].indexOf(parseInt(params.event_source)) === -1) { | |
throw 'Incorrect "event_source" parameter given: "' + params.event_source + '".\nMust be 0-4.'; | |
} | |
// Set "use_default_message" to true for non trigger-based events. | |
if (params.event_source !== '0') { | |
params.use_default_message = 'true'; | |
} | |
// Check {EVENT.VALUE} for trigger-based and internal events. | |
if (params.event_value !== '0' && params.event_value !== '1' | |
&& (params.event_source === '0' || params.event_source === '3')) { | |
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.'; | |
} | |
if (params.event_value == 0) { | |
params.event_nseverity = '6'; | |
} | |
if (!SEVERITY_COLORS[params.event_nseverity]) { | |
params.event_nseverity = '7'; | |
} | |
var request = new HttpRequest(), | |
factset = { | |
type: 'FactSet', | |
facts: [] | |
} | |
adaptivecard = { | |
'$schema': 'http://adaptivecards.io/schemas/adaptive-card.json', | |
type: 'AdaptiveCard', | |
version: '1.4', | |
body: [ | |
{ | |
type: 'Container', | |
items: [ | |
{ | |
type: 'TextBlock', | |
size: 'Medium', | |
weight: 'Bolder', | |
text: params.alert_subject | |
} | |
], | |
style: SEVERITY_COLORS[params.event_nseverity], | |
bleed: true | |
}, | |
{ | |
type: 'RichTextBlock', | |
inlines: [ | |
(params.use_default_message.toLowerCase() == 'true') | |
? params.alert_message | |
: params.trigger_description, | |
] | |
} | |
], | |
actions: [ | |
{ | |
type: 'Action.OpenUrl', | |
title: (params.event_source === '0') | |
? 'Event Info' | |
: 'Zabbix Home', | |
url: (params.event_source === '0') | |
? params.zabbix_url + '/tr_events.php?triggerid=' + | |
params.trigger_id + '&eventid=' + params.event_id | |
: params.zabbix_url | |
} | |
] | |
} | |
body = { | |
type: 'message', | |
attachments: [ | |
{ | |
contentType: 'application/vnd.microsoft.card.adaptive', | |
contentUrl: null, | |
} | |
] | |
}; | |
if (params.use_default_message.toLowerCase() !== 'true') { | |
// Problem message. | |
if (params.event_value === '1' && params.event_update_status === '0') { | |
factset.facts.push({ | |
title: 'Event time', | |
value: params.event_time + ' ' + params.event_date | |
}); | |
factset.facts.push({ | |
title: 'Host', | |
value: params.host_name + ' [' + params.host_ip + ']' | |
}); | |
} | |
// Update message. | |
else if (params.event_update_status === '1') { | |
adaptivecard.body[1].text = params.event_update_user + ' ' + params.event_update_action + '.'; | |
if (params.event_update_message) { | |
adaptivecard.body[1].text += '<br>Message:<br>' + params.event_update_message; | |
} | |
factset.facts.push({ | |
title: 'Event update time', | |
value: params.event_update_time + ' ' + params.event_update_date | |
}); | |
factset.facts.push({ | |
title: 'Host', | |
value: params.host_name + ' [' + params.host_ip + ']' | |
}); | |
} | |
// Resolved message. | |
else { | |
factset.facts.push({ | |
title: 'Recovery time', | |
value: params.event_recovery_time + ' ' + params.event_recovery_date | |
}); | |
factset.facts.push({ | |
title: 'Host', | |
value: params.host_name + ' [' + params.host_ip + ']' | |
}); | |
} | |
if (params.event_severity && params.event_severity !== '{EVENT.SEVERITY}') { | |
factset.facts.push({ | |
title: 'Severity', | |
value: params.event_severity | |
}); | |
} | |
if (params.event_opdata && params.event_opdata !== '{EVENT.OPDATA}') { | |
factset.facts.push({ | |
title: 'Operational data', | |
value: params.event_opdata | |
}); | |
} | |
if (params.event_tags && params.event_tags !== '{EVENT.TAGS}') { | |
factset.facts.push({ | |
title: 'Event tags', | |
value: params.event_tags | |
}); | |
} | |
Object.keys(params) | |
.forEach(function (key) { | |
if (key.startsWith('fact_') && params[key] !== '') { | |
factset.facts.push({ | |
title: key.substring(5), | |
value: params[key] | |
}); | |
} | |
else if (key.startsWith('openUri_') && params[key] !== '' && !params[key].startsWith('{')) { | |
adaptivecard.actions.push({ | |
type: 'Action.OpenUrl', | |
title: key.substring(8), | |
url: params[key] | |
}); | |
} | |
}); | |
adaptivecard.body.push(factset); | |
} | |
body.attachments[0].content = adaptivecard; | |
request.addHeader('Content-Type: application/json'); | |
if (typeof params.HTTPProxy === 'string' && params.HTTPProxy !== '') { | |
request.setProxy(params.HTTPProxy); | |
} | |
Zabbix.log(4, '[ MS Teams Webhook ] JSON: ' + JSON.stringify(body)); | |
var response = request.post(params.teams_endpoint, JSON.stringify(body)); | |
Zabbix.log(4, '[ MS Teams Webhook ] Response: ' + response); | |
var responsecode = request.getStatus(); | |
if (responsecode === 202) { | |
return 'OK'; | |
} | |
else { | |
Zabbix.log(4, '[ MS Teams Webhook ] FAILED with response code: ' + responsecode); | |
throw 'Response code: ' + responsecode; | |
} | |
} | |
catch (error) { | |
Zabbix.log(3, '[ MS Teams Webhook ] ERROR: ' + error); | |
throw 'Sending failed: ' + error; | |
} | |
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: {EVENT.NAME}' | |
message: | | |
Problem has been resolved in {EVENT.DURATION} at {EVENT.RECOVERY.TIME} on {EVENT.RECOVERY.DATE} | |
Problem name: {EVENT.NAME} | |
Host: {HOST.NAME} | |
Severity: {EVENT.SEVERITY} | |
Original problem ID: {EVENT.ID} | |
{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}. | |
{EVENT.UPDATE.MESSAGE} | |
Current problem status is {EVENT.STATUS}, 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} | |
- | |
event_source: SERVICE | |
operation_mode: PROBLEM | |
subject: 'Service "{SERVICE.NAME}" problem: {EVENT.NAME}' | |
message: | | |
Service problem started at {EVENT.TIME} on {EVENT.DATE} | |
Service problem name: {EVENT.NAME} | |
Service: {SERVICE.NAME} | |
Severity: {EVENT.SEVERITY} | |
Original problem ID: {EVENT.ID} | |
Service description: {SERVICE.DESCRIPTION} | |
{SERVICE.ROOTCAUSE} | |
- | |
event_source: SERVICE | |
operation_mode: RECOVERY | |
subject: 'Service "{SERVICE.NAME}" resolved in {EVENT.DURATION}: {EVENT.NAME}' | |
message: | | |
Service "{SERVICE.NAME}" has been resolved at {EVENT.RECOVERY.TIME} on {EVENT.RECOVERY.DATE} | |
Problem name: {EVENT.NAME} | |
Problem duration: {EVENT.DURATION} | |
Severity: {EVENT.SEVERITY} | |
Original problem ID: {EVENT.ID} | |
Service description: {SERVICE.DESCRIPTION} | |
- | |
event_source: SERVICE | |
operation_mode: UPDATE | |
subject: 'Changed "{SERVICE.NAME}" service status to {EVENT.UPDATE.SEVERITY} in {EVENT.AGE}' | |
message: | | |
Changed "{SERVICE.NAME}" service status to {EVENT.UPDATE.SEVERITY} at {EVENT.UPDATE.DATE} {EVENT.UPDATE.TIME}. | |
Current problem age is {EVENT.AGE}. | |
Service description: {SERVICE.DESCRIPTION} | |
{SERVICE.ROOTCAUSE} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This code does not allow the issue title to be placed in the notification header instead of "Card"