Ad Widget

Collapse

Teams Integration - Invalid MS Teams webhook

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • michael.weber
    Senior Member
    • Nov 2015
    • 121

    #1

    Teams Integration - Invalid MS Teams webhook

    Hello all,

    we have a Problem with MS Teams integration. At the moment we post message to a channel, that is working fine.
    Now we want to post other host group messages to a other team channel but after creating the webhook we will see the following message, if we hit the "Test" button in zabbix media type:
    Code:
    Sending failed: Invalid MS Teams webhook URL: https://<MSTENTANT>.webhook.office.com/webhookb2/586d2828-cb58-48f6-954d-d5de26c29795@0c6aa5a3-6531-4e28-9c0b-33ba1a8aa1ff/IncomingWebhook/bb06d61118274b82bfe4d9<TenRandomDigits>/4563618c-b03b-4e80-b093-28bb4ff11de8
    If we compare the webhooks url with the working one we see a other "syntax":
    Code:
    Working: https://outlook.office.com/webhook/d85e5931-7060-4a1e-91a4-9348cf6ab308@4650cfba-101d-44b1-8ef9-fcdae0705537/IncomingWebhook/f80f0195334542d5964343<TenRandomDigits>/7f6c83e2-d9d6-4198-97df-145077853b57
    Not Working:https://<MSTENTANT>.webhook.office.com/webhookb2/586d2828-cb58-48f6-954d-d5de26c29795@0c6aa5a3-6531-4e28-9c0b-33ba1a8aa1ff/IncomingWebhook/bb06d61118274b82bfe4d9<TenRandomDigits>/4563618c-b03b-4e80-b093-28bb4ff11de8
    We see, in the not working URL the MS Teams Tentant Name in front of ".webhook.office.com"..

    Is there a "URL Syntax" Check in zabbix an the "new" format is not valid?
    I already created a new webhook, same problem. The team/channel is created by a user with a valid "business standard" licence.

    Can some assist here? Were to begin troubleshooting? I think this is zabbix related, but i cant find the "regex" for the Teams webhook URL.

    Thank you all!
    Last edited by michael.weber; 08-01-2021, 00:23.
  • michael.weber
    Senior Member
    • Nov 2015
    • 121

    #2
    Found it after some troubleshooting:
    File zabbix-5.2.x/database/mysql/data.sql contains the following (check the bold text):
    Code:
    INSERT INTO `media_type` (`mediatypeid`,`type`,`name`,`smtp_server`,`smtp_h elo`,`smtp_email`,`exec_path`,`gsm_modem`,`usernam e`,`passwd`,`status`,`smtp_port`,`smtp_security`,` smtp_verify_peer`,`smtp_verify_host`,`smtp_authent ication`,`exec_params`,`maxsessions`,`maxattempts` ,`attempt_interval`,`content_type`,`script`,`timeo ut`,`process_tags`,`show_event_menu`,`event_menu_u rl`,`event_menu_name`,`description`) values ('14','4','MS Teams','','','','','','','','0','25','0','0','0',' 0','','1','3','10s','1','var SEVERITY_COLORS = [\r\n \'#97AAB3\', // Not classified.\r\n \'#7499FF\', // Information.\r\n \'#FFC859\', // Warning.\r\n \'#FFA059\', // Average.\r\n \'#E97659\', // High.\r\n \'#E45959\', // Disaster.\r\n \'#009900\', // Resolved.\r\n \'#000000\' // Default.\r\n];\r\n\r\ntry {\r\n var params = JSON.parse(value);\r\n\r\n if (!params.teams_endpoint) {\r\n throw \'Cannot get teams_endpoint\';\r\n }\r\n else if (![B]params.teams_endpoint.startsWith(\'https://outlook.office.com/webhook/[/B]\')) {\r\n throw \'Invalid MS Teams webhook URL: \' + params.teams_endpoint;\r\n }\r\n\r\n params.zabbix_url = (params.zabbix_url.endsWith(\'/\'))\r\n ? params.zabbix_url.slice(0, -1) : params.zabbix_url;\r\n\r\n if ([0, 1, 2, 3].indexOf(parseInt(params.event_source)) === -1) {\r\n throw \'Incorrect "event_source" parameter given: "\' + params.event_source + \'".\\nMust be 0-3.\';\r\n }\r\n\r\n // Set "use_default_message" to true for non trigger-based events.\r\n if (params.event_source !== \'0\') {\r\n params.use_default_message = \'true\';\r\n }\r\n\r\n // Check {EVENT.VALUE} for trigger-based and internal events.\r\n if (params.event_value !== \'0\' && params.event_value !== \'1\'\r\n && (params.event_source === \'0\' || params.event_source === \'3\')) {\r\n throw \'Incorrect "event_value" parameter given: "\' + params.event_value + \'".\\nMust be 0 or 1.\';\r\n }\r\n\r\n // Check {EVENT.UPDATE.STATUS} only for trigger-based events.\r\n if (params.event_update_status !== \'0\' && params.event_update_status !== \'1\' && params.event_source === \'0\') {\r\n throw \'Incorrect "event_update_status" parameter given: "\' + params.event_update_status + \'".\\nMust be 0 or 1.\';\r\n }\r\n\r\n if (params.event_value == 0) {\r\n params.event_nseverity = \'6\';\r\n }\r\n\r\n if (!SEVERITY_COLORS[params.event_nseverity]) {\r\n params.event_nseverity = \'7\';\r\n }\r\n\r\n var request = new CurlHttpRequest(),\r\n facts = [],\r\n body = {\r\n themeColor: SEVERITY_COLORS[params.event_nseverity].replace(\'#\', \'\'),\r\n summary: \'Zabbix\',\r\n sections: [\r\n {\r\n markdown: \'false\',\r\n activityTitle: params.alert_subject,\r\n activitySubtitle: \'On \' + params.host_name + \' [\' + params.host_ip + \']\',\r\n text: (params.use_default_message.toLowerCase() == \'true\')\r\n ? params.alert_message\r\n : params.trigger_description\r\n }\r\n ],\r\n potentialAction: [\r\n {\r\n \'@type\': \'OpenUri\',\r\n name: (params.event_source === \'0\')\r\n ? \'Event Info\'\r\n : \'Zabbix Home\',\r\n targets: [\r\n {\r\n os: \'default\',\r\n uri: (params.event_source === \'0\')\r\n ? params.zabbix_url + \'/tr_events.php?triggerid=\' +\r\n params.trigger_id + \'&eventid=\' + params.event_id\r\n : params.zabbix_url\r\n }\r\n ]\r\n }\r\n ]\r\n };\r\n\r\n if (params.use_default_message.toLowerCase() !== \'true\') {\r\n // Problem message.\r\n if (params.event_value === \'1\' && params.event_update_status === \'0\') {\r\n facts.push({\r\n name: \'Event time\',\r\n value: params.event_time + \' \' + params.event_date\r\n });\r\n }\r\n // Update message.\r\n else if (params.event_update_status === \'1\') {\r\n body.sections[0].text = params.event_update_user + \' \' + params.event_update_action + \'.\';\r\n\r\n if (params.event_update_message) {\r\n body.sections[0].text += \'<br>Message:<br>\' + params.event_update_message;\r\n }\r\n\r\n facts.push({\r\n name: \'Event update time\',\r\n value: params.event_update_time + \' \' + params.event_update_date\r\n });\r\n }\r\n // Resolved message.\r\n else {\r\n facts.push({\r\n name: \'Recovery time\',\r\n value: params.event_recovery_time + \' \' + params.event_recovery_date\r\n });\r\n }\r\n\r\n if (params.event_severity && params.event_severity !== \'{EVENT.SEVERITY}\') {\r\n facts.push({\r\n name: \'Severity\',\r\n value: params.event_severity\r\n });\r\n }\r\n\r\n\r\n if (params.event_opdata && params.event_opdata !== \'{EVENT.OPDATA}\') {\r\n facts.push({\r\n name: \'Operational data\',\r\n value: params.event_opdata\r\n });\r\n }\r\n\r\n if (params.event_tags && params.event_tags !== \'{EVENT.TAGS}\') {\r\n facts.push({\r\n name: \'Event tags\',\r\n value: params.event_tags\r\n });\r\n }\r\n\r\n Object.keys(params)\r\n .forEach(function (key) {\r\n if (key.startsWith(\'fact_\') && params[key] !== \'\') {\r\n facts.push({\r\n name: key.substring(5),\r\n value: params[key]\r\n });\r\n }\r\n else if (key.startsWith(\'openUri_\') && params[key] !== \'\' && !params[key].startsWith(\'{\')) {\r\n body.potentialAction.push({\r\n \'@type\': \'OpenUri\',\r\n name: key.substring(8),\r\n targets: [\r\n {\r\n os: \'default\',\r\n uri: params[key]\r\n }\r\n ]\r\n });\r\n }\r\n });\r\n body.sections[0].facts = facts;\r\n }\r\n\r\n body.sections[0].text = body.sections[0].text.replace(/(?:\\r\\n|\\r|\\n)/g, \'<br>\');\r\n\r\n request.AddHeader(\'Content-Type: application/json\');\r\n\r\n if (typeof params.HTTPProxy === \'string\' && params.HTTPProxy !== \'\') {\r\n request.SetProxy(params.HTTPProxy);\r\n }\r\n\r\n Zabbix.Log(4, \'[ MS Teams Webhook ] JSON: \' + JSON.stringify(body));\r\n\r\n var response = request.Post(params.teams_endpoint, JSON.stringify(body));\r\n\r\n Zabbix.Log(4, \'[ MS Teams Webhook ] Response: \' + response);\r\n\r\n if (response === \'1\') {\r\n return \'OK\';\r\n }\r\n else {\r\n Zabbix.Log(4, \'[ MS Teams Webhook ] FAILED with response: \' + response);\r\n throw response;\r\n }\r\n}\r\ncatch (error) {\r\n Zabbix.Log(3, \'[ MS Teams Webhook ] ERROR: \' + error);\r\n throw \'Sending failed: \' + error;\r\n}','30s','0','0','','','');
    ./database/sqlite3/data.sql:
    Code:
    else if (![B]params.teams_endpoint.startsWith(''https://outlook.office.com/webhook/[/B]'')) {
    ./database/postgresql/data.sql:
    Code:
    else if (![B]params.teams_endpoint.startsWith(''https://outlook.office.com/webhook/[/B]'')) {
    ./database/oracle/data.sql:
    Code:
    values ('14','4','MS Teams','','','','','','','','0','25','0','0','0',' 0','','1','3','10s','1',TO_NCLOB('var SEVERITY_COLORS = [' || chr(13) || chr(10) || ' ''#97AAB3'', // Not classified.' || chr(13) || chr(10) || ' ''#7499FF'', // Information.' || chr(13) || chr(10) || ' ''#FFC859'', // Warning.' || chr(13) || chr(10) || ' ''#FFA059'', // Average.' || chr(13) || chr(10) || ' ''#E97659'', // High.' || chr(13) || chr(10) || ' ''#E45959'', // Disaster.' || chr(13) || chr(10) || ' ''#009900'', // Resolved.' || chr(13) || chr(10) || ' ''#000000'' // Default.' || chr(13) || chr(10) || '];' || chr(13) || chr(10) || '' || chr(13) || chr(10) || 'try {' || chr(13) || chr(10) || ' var params = JSON.parse(value);' || chr(13) || chr(10) || '' || chr(13) || chr(10) || ' if (!params.teams_endpoint) {' || chr(13) || chr(10) || ' throw ''Cannot get teams_endpoint'';' || chr(13) || chr(10) || ' }' || chr(13) || chr(10) || ' else if (![B]params.teams_endpoint.startsWith(''https://outlook.office.com/webhook/[/B]'')) {' || chr(13) || chr(10) || ' throw ''Invalid MS Teams webhook URL: '' + params.teams_endpoint;' || chr(13) || chr(10) || ' }' || chr(13) || chr(10) || '' || chr(13) || chr(10) || ' params.zabbix_url = (params.zabbix_url.endsWith(''/''))' || chr(13) || chr(10) || ' ? params.zabbix_url.slice(0, -1) : params.zabbix_url;' || chr(13) || chr(10) || '' || chr(13) || chr(10) || ' if ([0, 1, 2, 3].indexOf(parseInt(params.event_source)) === -1) {' || chr(13) || chr(10) || ' throw ''Incorrect "event_source" parameter given: "'' + params.event_source + ''".\nMust be 0-3.'';' || chr(13) || chr(10) || ' }' || chr(13) || chr(10) || '' || chr(13) || chr(10) || ' // Set "use_default_message" to true for non trigger-based events.' || chr(13) || chr(10) || ' if (params.event_source !== ''0'') {' || chr(13) || chr(10) || ' params.use_default_message = ''true'';' || chr(13) || chr(10) || ' }' || chr(13) || chr(10) || '' || chr(13) || chr(10) || ' // Check {EVENT.VALUE} for trigger-based and internal events.' || chr(13) || chr(10) || '')||
    I adjusted the column script in the SQL table media_type. Now i can create the mediatype with the new webhook URL.
    Click image for larger version  Name:	teams.PNG Views:	0 Size:	57.1 KB ID:	416371
    Replaced line 18:
    Code:
    else if (!params.teams_endpoint.startsWith('https://outlook.office.com/webhook/')) {
    with
    Code:
    else if (!params.teams_endpoint.includes('office.com/webhook')) {
    If this is working i will create a new Bug Report in System Dashboard - ZABBIX SUPPORT if everything is working as expected.

    I will updates with Topic with more information within 24 hours

    Update:
    everything is working with the "new" webhook URL, going to fill out a new bugreport on System Dashboard - ZABBIX SUPPORT tomorrow. This Topic can be closed, perhaps someone else is facing the same problem and can implement this "workaround" while we are waiting for the official implementation
    Click image for larger version  Name:	teams_ok.PNG Views:	0 Size:	25.2 KB ID:	416377
    Zabbix Issue Link: [ZBX-18853] Invalid MS Teams webhook because of new URL syntax - ZABBIX SUPPORT
    Last edited by michael.weber; 08-01-2021, 10:11. Reason: Added Zabbix Issue link

    Comment

    • jpsbatista
      Junior Member
      • Apr 2021
      • 1

      #3
      Good work Michael, but this update is possible in media type> script

      Comment

      • jonasgribas
        Junior Member
        • Jan 2019
        • 3

        #4
        Good Work Michel. Thanks.

        Comment

        • johndoe2374
          Member
          • Aug 2021
          • 80

          #5
          Well, the issue has been closed already, why creating new bugreport then? Microsoft have changed their URI format, so media type template was updated. Just import a new one and re-create your channel connectors:

          Comment


          • johndoe2374
            johndoe2374 commented
            Editing a comment
            Sorry, didn't check the OP posting date
        • cfrancis
          Junior Member
          • Jun 2019
          • 17

          #6
          Excelente trabajo, muchas gracias por tu aportación Michael.

          Saludos.

          Comment

          Working...