Advertisement
Guest User

Untitled

a guest
Sep 21st, 2022
191
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. var SEVERITY_COLORS = [
  2.     '#97AAB3', '#7499FF', '#FFC859',
  3.     '#FFA059', '#E97659', '#E45959'
  4. ];
  5.  
  6. var RESOLVE_COLOR = '#009900';
  7.  
  8. var SLACK_MODE_HANDLERS = {
  9.     alarm: handlerAlarm,
  10.     event: handlerEvent
  11. };
  12.  
  13.  
  14. if (!String.prototype.format) {
  15.     String.prototype.format = function() {
  16.         var args = arguments;
  17.  
  18.         return this.replace(/{(\d+)}/g, function(match, number) {
  19.             return number in args
  20.                 ? args[number]
  21.                 : match
  22.             ;
  23.         });
  24.     };
  25. }
  26.  
  27. function isEventProblem(params) {
  28.     return params.event_value == 1
  29.         && params.event_update_status == 0
  30.     ;
  31. }
  32.  
  33. function isEventUpdate(params) {
  34.     return params.event_value == 1
  35.         && params.event_update_status == 1
  36.     ;
  37. }
  38.  
  39. function isEventResolve(params) {
  40.     return params.event_value == 0;
  41. }
  42.  
  43. function getPermalink(channelId, messageTimestamp) {
  44.     var req = new HttpRequest();
  45.  
  46.     if (typeof params.HTTPProxy === 'string' && params.HTTPProxy.trim() !== '') {
  47.         req.setProxy(params.HTTPProxy);
  48.     }
  49.  
  50.     req.addHeader('Content-Type: application/x-www-form-urlencoded; charset=utf-8');
  51.     req.addHeader('Authorization: Bearer ' + params.bot_token);
  52.  
  53.     var query = '{0}?channel={1}&message_ts={2}'.format(
  54.             Slack.getPermalink,
  55.             encodeURIComponent(channelId),
  56.             encodeURIComponent(messageTimestamp)),
  57.         resp = JSON.parse(req.get(query));
  58.  
  59.     if (req.getStatus() != 200 || !resp.ok || resp.ok === 'false') {
  60.         throw 'message was created, but getting message link was failed with reason "' + resp.error + '"';
  61.     }
  62.  
  63.     return resp.permalink;
  64. }
  65.  
  66. function createProblemURL(zabbix_url, triggerid, eventid, event_source) {
  67.     var problem_url = '';
  68.     if (event_source === '0') {
  69.         problem_url = '{0}/tr_events.php?triggerid={1}&eventid={2}'
  70.             .format(
  71.                 zabbix_url,
  72.                 triggerid,
  73.                 eventid
  74.             );
  75.     }
  76.     else {
  77.         problem_url = zabbix_url;
  78.     }
  79.  
  80.     return problem_url;
  81. }
  82.  
  83. function handlerAlarm(params) {
  84.     var fields = {
  85.         channel: params.channel,
  86.         as_user: params.slack_as_user,
  87.     };
  88.  
  89.     if (isEventProblem(params)) {
  90.         fields.attachments = [
  91.             createMessage(
  92.                 SEVERITY_COLORS[params.event_nseverity] || 0,
  93.                 params.event_date,
  94.                 params.event_time,
  95.                 createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source)
  96.             )
  97.         ];
  98.  
  99.         var resp = JSON.parse(req.post(Slack.postMessage, JSON.stringify(fields)));
  100.  
  101.         if (req.getStatus() != 200 || !resp.ok || resp.ok === 'false') {
  102.             throw resp.error;
  103.         }
  104.  
  105.         result.tags = {
  106.             ['__message_ts_' + params.channel]: resp.ts,
  107.             ['__channel_id_' + params.channel]: resp.channel,
  108.             ['__message_link_' + params.channel]: getPermalink(resp.channel, resp.ts),
  109.         };
  110.  
  111.     }
  112.     else if (isEventUpdate(params)) {
  113.         try {
  114.             var channel_event_tags = JSON.parse(params.event_tags);
  115.         } catch (error) {
  116.             throw 'Cant process event tags: ' + error;
  117.         }
  118.  
  119.         if (Array.isArray(channel_event_tags)) {
  120.             for (i in channel_event_tags) {
  121.                 if (channel_event_tags[i].tag.includes('__message_ts_' + params.channel)) {
  122.                     fields.thread_ts = channel_event_tags[i].value;
  123.                     break;
  124.                 }
  125.             }
  126.         }
  127.  
  128.         fields.attachments = [
  129.             createMessage(
  130.                 SEVERITY_COLORS[params.event_nseverity] || 0,
  131.                 params.event_update_date,
  132.                 params.event_update_time,
  133.                 createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source),
  134.                 true
  135.             )
  136.         ];
  137.  
  138.         resp = JSON.parse(req.post(Slack.postMessage, JSON.stringify(fields)));
  139.  
  140.         if (req.getStatus() != 200 || !resp.ok || resp.ok === 'false') {
  141.             throw resp.error;
  142.         }
  143.  
  144.     }
  145.     else if (isEventResolve(params)) {
  146.  
  147.         fields.text = '';
  148.  
  149.         try {
  150.             var channel_event_tags = JSON.parse(params.event_tags);
  151.         } catch (error) {
  152.             throw 'Cant process event tags: ' + error;
  153.         }
  154.  
  155.         if (Array.isArray(channel_event_tags)) {
  156.             for (i in channel_event_tags) {
  157.                 if (channel_event_tags[i].tag.includes('__channel_id_' + params.channel)) {
  158.                     fields.channel = channel_event_tags[i].value;
  159.                     continue;
  160.                 }
  161.                 if (channel_event_tags[i].tag.includes('__message_ts_' + params.channel)) {
  162.                     fields.ts = channel_event_tags[i].value;
  163.                 }
  164.             }
  165.         }
  166.  
  167.         fields.attachments = [
  168.             createMessage(
  169.                 RESOLVE_COLOR,
  170.                 params.event_date,
  171.                 params.event_time,
  172.                 createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source)
  173.             )
  174.         ];
  175.  
  176.         resp = JSON.parse(req.post(Slack.chatUpdate, JSON.stringify(fields)));
  177.         if (req.getStatus() != 200 || !resp.ok || resp.ok === 'false') {
  178.             throw resp.error;
  179.         }
  180.     }
  181. }
  182.  
  183. function handlerEvent(params) {
  184.     var fields = {
  185.         channel: params.channel,
  186.         as_user: params.slack_as_user
  187.     };
  188.  
  189.     if (isEventProblem(params)) {
  190.         fields.attachments = [
  191.             createMessage(
  192.                 SEVERITY_COLORS[params.event_nseverity] || 0,
  193.                 params.event_date,
  194.                 params.event_time,
  195.                 createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source)
  196.             )
  197.         ];
  198.  
  199.         var resp = JSON.parse(req.post(Slack.postMessage, JSON.stringify(fields)));
  200.  
  201.         if (req.getStatus() != 200 || !resp.ok || resp.ok === 'false') {
  202.             throw resp.error;
  203.         }
  204.  
  205.         result.tags = {
  206.             ['__message_link_' + params.channel]: getPermalink(resp.channel, resp.ts)
  207.         }
  208.  
  209.     }
  210.     else if (isEventUpdate(params)) {
  211.         fields.attachments = [
  212.             createMessage(
  213.                 SEVERITY_COLORS[params.event_nseverity] || 0,
  214.                 params.event_update_date,
  215.                 params.event_update_time,
  216.                 createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source),
  217.                 false
  218.             )
  219.         ];
  220.  
  221.         resp = JSON.parse(req.post(Slack.postMessage, JSON.stringify(fields)));
  222.  
  223.         if (req.getStatus() != 200 || !resp.ok || resp.ok === 'false') {
  224.             throw resp.error;
  225.         }
  226.  
  227.     }
  228.     else if (isEventResolve(params)) {
  229.         fields.attachments = [
  230.             createMessage(
  231.                 RESOLVE_COLOR,
  232.                 params.event_recovery_date,
  233.                 params.event_recovery_time,
  234.                 createProblemURL(params.zabbix_url, params.trigger_id, params.event_id, params.event_source)
  235.             )
  236.         ];
  237.  
  238.         resp = JSON.parse(req.post(Slack.postMessage, JSON.stringify(fields)));
  239.  
  240.         if (req.getStatus() != 200 || !resp.ok || resp.ok === 'false') {
  241.             throw resp.error;
  242.         }
  243.     }
  244. }
  245.  
  246. function createMessage(
  247.     event_severity_color,
  248.     event_date,
  249.     event_time,
  250.     problem_url,
  251.     isShort,
  252.     messageText
  253. ) {
  254.     var message = {
  255.         fallback: params.alert_subject,
  256.         title: params.alert_subject,
  257.         color: event_severity_color,
  258.         title_link: problem_url,
  259.         pretext: messageText || '',
  260.  
  261.         fields: [
  262.             {
  263.                 title: 'Host',
  264.                 value: '{0} [{1}]'.format(params.host_name, params.host_conn),
  265.                 short: true
  266.             },
  267.             {
  268.                 title: 'Event time',
  269.                 value: '{0} {1}'.format(event_date, event_time),
  270.                 short: true
  271.             }
  272.         ],
  273.     };
  274.  
  275.     if (params.event_source === '0') {
  276.         message.fields.push(
  277.             {
  278.                 title: 'Severity',
  279.                 value: params.event_severity,
  280.                 short: true
  281.             },
  282.             {
  283.                 title: 'Opdata',
  284.                 value: params.event_opdata,
  285.                 short: true
  286.             }
  287.         );
  288.     }
  289.  
  290.     if (!isShort  && params.event_source === '0') {
  291.         message['actions'] = [
  292.             {
  293.                 type: 'button',
  294.                 text: 'Open in Zabbix',
  295.                 url: problem_url
  296.             }
  297.         ];
  298.  
  299.         message.fields.push(
  300.             {
  301.                 title: 'Event tags',
  302.                 value: JSON.parse(params.event_tags).filter(function (e) { return !e.tag.includes('__') }).map(function (e) { return e.tag + ': ' + e.value }).join('\n') || 'None',
  303.                 short: true
  304.             },
  305.             {
  306.                 title: 'Trigger description',
  307.                 value: params.trigger_description,
  308.                 short: true
  309.             }
  310.         );
  311.     }
  312.  
  313.     if (params.event_source !== '0' || params.event_update_status === '1') {
  314.         message.fields.push(
  315.             {
  316.                 title: 'Details',
  317.                 value: params.alert_message,
  318.                 short: false
  319.             }
  320.         );
  321.     }
  322.  
  323.     return message;
  324. }
  325.  
  326. function validateParams(params) {
  327.     if (typeof params.bot_token !== 'string' || params.bot_token.trim() === '') {
  328.         throw 'Field "bot_token" cannot be empty';
  329.     }
  330.  
  331.     if (typeof params.channel !== 'string' || params.channel.trim() === '') {
  332.         throw 'Field "channel" cannot be empty';
  333.     }
  334.  
  335.     if (isNaN(params.event_id)) {
  336.         throw 'Field "event_id" is not a number';
  337.     }
  338.  
  339.     if ([0, 1, 2, 3].indexOf(parseInt(params.event_source)) === -1) {
  340.         throw 'Incorrect "event_source" parameter given: "' + params.event_source + '".\nMust be 0-3.';
  341.     }
  342.  
  343.     if (params.event_source !== '0') {
  344.         params.event_nseverity = '0';
  345.         params.event_severity = 'Not classified';
  346.         params.event_update_status = '0';
  347.         params.slack_mode = 'event';
  348.     }
  349.  
  350.     if (params.event_source === '1' || params.event_source === '2') {
  351.         params.event_value = '1';
  352.     }
  353.  
  354.     if (params.event_source === '1') {
  355.         params.host_name = params.discovery_host_dns;
  356.         params.host_ip = params.discovery_host_ip;
  357.     }
  358.  
  359.     if (!~[0, 1, 2, 3, 4, 5].indexOf(parseInt(params.event_nseverity))) {
  360.         throw 'Incorrect "event_nseverity" parameter given: ' + params.event_nseverity + '\nMust be 0-5.';
  361.     }
  362.  
  363.     if (typeof params.event_severity !== 'string' || params.event_severity.trim() === '') {
  364.         throw 'Field "event_severity" cannot be empty';
  365.     }
  366.  
  367.     if (params.event_update_status !== '0' && params.event_update_status !== '1') {
  368.         throw 'Incorrect "event_update_status" parameter given: ' + params.event_update_status + '\nMust be 0 or 1.';
  369.     }
  370.  
  371.     if (params.event_value !== '0' && params.event_value !== '1') {
  372.         throw 'Incorrect "event_value" parameter given: ' + params.event_value + '\nMust be 0 or 1.';
  373.     }
  374.  
  375.     if (typeof params.host_conn !== 'string' || params.host_conn.trim() === '') {
  376.         throw 'Field "host_conn" cannot be empty';
  377.     }
  378.  
  379.     if (typeof params.host_name !== 'string' || params.host_name.trim() === '') {
  380.         throw 'Field "host_name" cannot be empty';
  381.     }
  382.  
  383.     if (!~['true', 'false'].indexOf(params.slack_as_user.toLowerCase())) {
  384.         throw 'Incorrect "slack_as_user" parameter given: ' + params.slack_as_user + '\nMust be "true" or "false".';
  385.     }
  386.  
  387.     if (!~['alarm', 'event'].indexOf(params.slack_mode)) {
  388.         throw 'Incorrect "slack_mode" parameter given: ' + params.slack_mode + '\nMust be "alarm" or "event".';
  389.     }
  390.  
  391.     if (isNaN(params.trigger_id) && params.event_source === '0') {
  392.         throw 'field "trigger_id" is not a number';
  393.     }
  394.  
  395.     if (typeof params.zabbix_url !== 'string' || params.zabbix_url.trim() === '') {
  396.         throw 'Field "zabbix_url" cannot be empty';
  397.     }
  398.  
  399.     if (!/^(http|https):\/\/.+/.test(params.zabbix_url)) {
  400.         throw 'Field "zabbix_url" must contain a schema';
  401.     }
  402. }
  403.  
  404. try {
  405.     var params = JSON.parse(value);
  406.  
  407.     validateParams(params);
  408.  
  409.     var req = new HttpRequest(),
  410.         result = {tags: {}};
  411.  
  412.     if (typeof params.HTTPProxy === 'string' && params.HTTPProxy.trim() !== '') {
  413.         req.setProxy(params.HTTPProxy);
  414.     }
  415.  
  416.     req.addHeader('Content-Type: application/json; charset=utf-8');
  417.     req.addHeader('Authorization: Bearer ' + params.bot_token);
  418.  
  419.     var slack_endpoint = 'https://slack.com/api/';
  420.  
  421.     var Slack = {
  422.         postMessage: slack_endpoint + 'chat.postMessage',
  423.         getPermalink: slack_endpoint + 'chat.getPermalink',
  424.         chatUpdate: slack_endpoint + 'chat.update'
  425.     };
  426.  
  427.     params.slack_mode = params.slack_mode.toLowerCase();
  428.     params.slack_mode = params.slack_mode in SLACK_MODE_HANDLERS
  429.         ? params.slack_mode
  430.         : 'alarm';
  431.  
  432.     SLACK_MODE_HANDLERS[params.slack_mode](params);
  433.  
  434.     if (params.event_source === '0') {
  435.         return JSON.stringify(result);
  436.     }
  437.     else {
  438.         return 'OK';
  439.     }
  440. }
  441. catch (error) {
  442.     Zabbix.log(4, '[ Slack Webhook ] Slack notification failed : ' + error);
  443.     throw 'Slack notification failed : ' + error;
  444. }
Tags: Zabbix_Slack
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement