Telegram Notification Script FIX for cmk2.0

Hello together,

I fixxed the Telegram Notification Script for the new Check MK Version:

thanks to mk@mathias-kettner.de and Stefan Gehn stefan+cmk@srcxbox.net for providing the initial script.

#!/usr/bin/env python3
# Telegram cmk2.0


import os, re, sys
from urllib.request import urlopen
import urllib.parse
import ssl
import urllib.request

ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

def fetch_notification_context():
    context = {}
    for (var, value) in os.environ.items():
        if var.startswith("NOTIFY_"):
            context[var[7:]] = value
    return context

tmpl_host_text = """*Check_MK: $HOSTNAME$ - $EVENT_TXT$*
```
Host:     $HOSTNAME$
Alias:    $HOSTALIAS$
Address:  $HOSTADDRESS$
Event:    $EVENT_TXT$
Output:   $HOSTOUTPUT$

$LONGHOSTOUTPUT$```"""

tmpl_service_text = """*Check_MK: $HOSTNAME$/$SERVICEDESC$ $EVENT_TXT$*
```
Host:     $HOSTNAME$
Alias:    $HOSTALIAS$
Address:  $HOSTADDRESS$
Service:  $SERVICEDESC$
Event:    $EVENT_TXT$
Output:   $SERVICEOUTPUT$

$LONGSERVICEOUTPUT$```"""

def substitute_context(template, context):
    # First replace all known variables
    for varname, value in context.items():
        template = template.replace('$'+varname+'$', value)

    # Remove the rest of the variables and make them empty
    template = re.sub("\$[A-Z_][A-Z_0-9]*\$", "", template)
    return template

def construct_message_text(context):
    notification_type = context["NOTIFICATIONTYPE"]
    if notification_type in [ "PROBLEM", "RECOVERY" ]:
        txt_info = "$PREVIOUS@HARDSHORTSTATE$ -> $@SHORTSTATE$"
    elif notification_type.startswith("FLAP"):
        if "START" in notification_type:
            txt_info = "Started Flapping"
        else:
            txt_info = "Stopped Flapping ($@SHORTSTATE$)"
    elif notification_type.startswith("DOWNTIME"):
        what = notification_type[8:].title()
        txt_info = "Downtime " + what + " ($@SHORTSTATE$)"
    elif notification_type == "ACKNOWLEDGEMENT":
        txt_info = "Acknowledged ($@SHORTSTATE$)"
    elif notification_type == "CUSTOM":
        txt_info = "Custom Notification ($@SHORTSTATE$)"
    else:
        txt_info = notification_type # Should neven happen

    txt_info = substitute_context(txt_info.replace("@", context["WHAT"]), context)

    context["EVENT_TXT"] = txt_info

    if context['WHAT'] == 'HOST':
        tmpl_text = tmpl_host_text
    else:
        tmpl_text = tmpl_service_text
        
    return substitute_context(tmpl_text, context)

def send_telegram_message(token, chat_id, text):
    url = 'https://api.telegram.org/bot%s/sendMessage' % (token)
    data = urllib.parse.urlencode({'chat_id':chat_id, 'text':text, 'parse_mode':'Markdown'}).encode("utf-8")
    urlopen(url, data=data, context=ctx).read()

#### CHANGE THESE ####
tg_token = '00000:XXXXXXXXXXXXXXXXXXXXXXXXX'
chat_id = '0000000'

context = fetch_notification_context()
text = construct_message_text(context)
send_telegram_message(tg_token, chat_id, text)

Just put it in ~/local/share/check_mk/notifications/ and configure it in the GUI.

Hope it helps you :slight_smile:

4 Likes

There is also this alternative that I found on Github.
Works with Checkmk 2.0.0.

1 Like

Your script its the most pretty for telegram notification on Cmk2.0 :slightly_smiling_face:
Thank you

Can Telegram notifications be integrated officially please? The same goes for Rocket.Chat which is used by many.

Thanks!

With some check strings from snmp devices (checkpoint FW) we had some problems with temperature output, and got this error:

2021-12-01 12:33:38      executing /omd/sites/site/local/share/check_mk/notifications/telegram.py
2021-12-01 12:33:38      Output: Traceback (most recent call last):
2021-12-01 12:33:38      Output:   File "/omd/sites/site/local/share/check_mk/notifications/telegram.py", line 119, in <module>
2021-12-01 12:33:38      Output:     main()
2021-12-01 12:33:38      Output:   File "/omd/sites/site/local/share/check_mk/notifications/telegram.py", line 117, in main
2021-12-01 12:33:38      Output:     send_telegram_message(telegram_bot_token, telegram_chatid, text)
2021-12-01 12:33:38      Output:   File "/omd/sites/site/local/share/check_mk/notifications/telegram.py", line 103, in send_telegram_message
2021-12-01 12:33:38      Output:     data = urllib.parse.urlencode({'chat_id':chat_id, 'text':text, 'parse_mode':'Markdown'}).encode("utf-8")
2021-12-01 12:33:38      Output:   File "/usr/lib/python3.6/urllib/parse.py", line 913, in urlencode
2021-12-01 12:33:38      Output:     v = quote_via(str(v), safe, encoding, errors)
2021-12-01 12:33:38      Output:   File "/usr/lib/python3.6/urllib/parse.py", line 841, in quote_plus
2021-12-01 12:33:38      Output:     string = quote(string, safe + space, encoding, errors)
2021-12-01 12:33:38      Output:   File "/usr/lib/python3.6/urllib/parse.py", line 819, in quote
2021-12-01 12:33:38      Output:     string = string.encode(encoding, errors)
2021-12-01 12:33:38      Output: UnicodeEncodeError: 'utf-8' codec can't encode characters in position 232-233: surrogates not allowed
2021-12-01 12:33:38      Plugin exited with code 1
2021-12-01 12:33:38      Output:   File "/usr/lib/python2.7/os.py", line 473, in __setitem__
2021-12-01 12:33:38      Output:     putenv(key, item)
2021-12-01 12:33:38      Output: UnicodeEncodeError: 'ascii' codec can't encode character u'\xb0' in position 12: ordinal not in range(128)

I fixed this with errors=“ignore” in the encode call in function send_telegram_message:

    data = urllib.parse.urlencode({'chat_id':chat_id, 'text':text, 'parse_mode':'Markdown'}).encode("utf-8", errors="ignore")

The Problem is this character: °
OK - 49.0 °C

Interesting is that this script has Python2 and Python3 libraries involved. Also there are libraries from inside CMK and outside from the system.
It is possible if this library problem is fixed also the unicode problem will be gone.

I would love for CMK to officially support more notification backends.