-
-
Save n00rm/32f1334b1dd2efc40122fee36551ef17 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3 | |
# Notify via Discord | |
import os | |
import requests | |
import sys | |
USERNAME = "check_mk" | |
AVATARURL = "https://checkmk.com/favicon-96x96.png" | |
COLORS = { | |
"CRITICAL": "15597568", | |
"DOWN": "15597568", | |
"WARNING": "16768256", | |
"OK": "52224", | |
"UP": "52224", | |
"UNKNOWN": "13421772", | |
"UNREACHABLE": "13421772", | |
} | |
def discord_msg(context): | |
"""Build the message for discord""" | |
facts = [] | |
if context.get('WHAT', None) == "SERVICE": | |
state = context["SERVICESTATE"] | |
color = COLORS.get(state) | |
subtitle = "Service Notification" | |
facts.append({"name": "Service:", "value": context["SERVICEDESC"]}) | |
output = context["SERVICEOUTPUT"] if context["SERVICEOUTPUT"] else "" | |
else: | |
state = context["HOSTSTATE"] | |
color = COLORS.get(state) | |
subtitle = "Host Notification" | |
output = context["HOSTOUTPUT"] if context["HOSTOUTPUT"] else "" | |
facts.extend([ | |
{ | |
"name": "Host:", | |
"value": context["HOSTNAME"] | |
}, | |
{ | |
"name": "State:", | |
"value": state | |
} | |
]) | |
return { | |
"username": USERNAME, | |
"avatar_url": AVATARURL, | |
"embeds": [ | |
{ | |
"title": subtitle, | |
"color": color, | |
"fields": facts, | |
"footer": { | |
"text": output | |
} | |
} | |
] | |
} | |
def collect_context(): | |
return { | |
var[7:]: value | |
for (var, value) in os.environ.items() | |
if var.startswith("NOTIFY_") | |
} | |
def post_request(message_constructor, success_code=204): | |
context = collect_context() | |
url = context.get("PARAMETERS") | |
r = requests.post(url=url, json=message_constructor(context)) | |
if r.status_code == success_code: | |
sys.exit(0) | |
else: | |
sys.stderr.write( | |
"Failed to send notification. Status: %i, Response: %s\n" % (r.status_code, r.text)) | |
sys.exit(2) | |
if __name__ == "__main__": | |
post_request(discord_msg) |
Hi,
der Skript darf nur mit einem Benutzer aufgerufen werden. Bitte benutze den automation user dafür. Das sollte dein Problem lösen. 😉
Hehe, wie bereits im CheckMK Forum geschrieben, hast vollkommen recht 😄 Hier war ein Noob mal wieder am Werk
Hey there,
Sure it does. You must setup on CheckMK when he should notify snd over which way :)
Hey Guys,
Edit, managed to get it working but getting the following error now:
cat notify.log
2022-01-24 02:00:59,353 [20] [cmk.base.notify] ----------------------------------------------------------------------
2022-01-24 02:00:59,353 [20] [cmk.base.notify] Got raw notification (UNKNOWN) context with 0 variables
2022-01-24 02:00:59,353 [20] [cmk.base.events] Error on completing raw context: 'HOSTNAME'
2022-01-24 02:00:59,354 [40] [cmk.base.notify] ERROR:
Traceback (most recent call last):
File "/omd/sites/ad/lib/python3/cmk/base/notify.py", line 355, in locally_deliver_raw_context
return notify_rulebased(raw_context, analyse=analyse)
File "/omd/sites/ad/lib/python3/cmk/base/notify.py", line 474, in notify_rulebased
why_not = rbn_match_rule(rule, raw_context)
File "/omd/sites/ad/lib/python3/cmk/base/notify.py", line 804, in rbn_match_rule
return events.apply_matchers([
File "/omd/sites/ad/lib/python3/cmk/base/events.py", line 414, in apply_matchers
result = matcher(rule, context)
File "/omd/sites/ad/lib/python3/cmk/base/events.py", line 421, in event_match_rule
return apply_matchers([
File "/omd/sites/ad/lib/python3/cmk/base/events.py", line 414, in apply_matchers
result = matcher(rule, context)
File "/omd/sites/ad/lib/python3/cmk/base/events.py", line 675, in event_match_exclude_hosts
if context["HOSTNAME"] in rule.get("match_exclude_hosts", []):
KeyError: 'HOSTNAME'
Thanks
Hi,
I answered your forum post to you problem.
Have a look and let me know if it helps you -> https://forum.checkmk.com/t/check-mk-discord-notification/29311/4?u=norm
Kind Regards
Norm
Hi Norm,
Is there any way to have this script use the webhook with the 'role mention role id' so it can @ tag people?
I assume maybe somewhere here?
def post_request(message_constructor, success_code=204):
context = collect_context()
url = context.get("PARAMETERS")
r = requests.post(url=url, json=message_constructor(context))
Thanks,
C
Hi @qhgh
yes it should be pretty easy to add that function.
You can use the Enviroment Variables to get that info to the script.
https://docs.checkmk.com/latest/en/notifications.html#_environment_variables
You could use the Pager ID as a mention Role ID or create multiple notification rule with the mention id as a parameter and use the NOTIFY_PARAMETER_2 variable.
#!/usr/bin/env python3
# Notify via Discord
import os
import requests
import sys
USERNAME = "check_mk"
AVATARURL = "https://checkmk.com/favicon-96x96.png"
COLORS = {
"CRITICAL": "15597568",
"DOWN": "15597568",
"WARNING": "16768256",
"OK": "52224",
"UP": "52224",
"UNKNOWN": "13421772",
"UNREACHABLE": "13421772",
}
# Add the role mention ID here
# you could also use Variables from here https://docs.checkmk.com/latest/en/notifications.html#_environment_variables
ROLE_MENTION_ID = "your_role_id"
def discord_msg(context):
"""Build the message for discord"""
facts = []
if context.get('WHAT', None) == "SERVICE":
state = context["SERVICESTATE"]
color = COLORS.get(state)
subtitle = "Service Notification"
facts.append({"name": "Service:", "value": context["SERVICEDESC"]})
output = context["SERVICEOUTPUT"] if context["SERVICEOUTPUT"] else ""
else:
state = context["HOSTSTATE"]
color = COLORS.get(state)
subtitle = "Host Notification"
output = context["HOSTOUTPUT"] if context["HOSTOUTPUT"] else ""
facts.extend([
{
"name": "Host:",
"value": context["HOSTNAME"]
},
{
"name": "State:",
"value": state
}
])
mention = f"<@&{ROLE_MENTION_ID}>"
return {
"username": USERNAME,
"avatar_url": AVATARURL,
"content": mention, # Add the role mention here
"embeds": [
{
"title": subtitle,
"color": color,
"fields": facts,
"footer": {
"text": output
}
}
]
}
# Rest of the code...
Hope this helps.
Thanks very much n00m!
I gave it a try but it errors:
2023-05-12 14:19:11 * notifying discord via xnewdiscord.py, parameters: https://discord.com/api/webhooks/example, bulk: no
2023-05-12 14:19:11 executing /omd/sites/dc1/local/share/check_mk/notifications/xnewdiscord.py
2023-05-12 14:19:11 Output: File "/omd/sites/dc1/local/share/check_mk/notifications/xnewdiscord.py", line 92
2023-05-12 14:19:11 Output: post_request(discord_msg).
2023-05-12 14:19:11 Output: ^
2023-05-12 14:19:11 Output: SyntaxError: invalid syntax
2023-05-12 14:19:11 Plugin exited with code 1
I have the file like so:
#!/usr/bin/env python3
# n00m Notify via Discord
import os
import requests
import sys
USERNAME = "check_mk"
AVATARURL = "https://checkmk.com/favicon-96x96.png"
COLORS = {
"CRITICAL": "15597568",
"DOWN": "15597568",
"WARNING": "16768256",
"OK": "52224",
"UP": "52224",
"UNKNOWN": "13421772",
"UNREACHABLE": "13421772",
}
# Add the role mention ID here
# you could also use Variables from here https://docs.checkmk.com/latest/en/notifications.html#_environment_variables
ROLE_MENTION_ID = "123example123"
def discord_msg(context):
"""Build the message for discord"""
facts = []
if context.get('WHAT', None) == "SERVICE":
state = context["SERVICESTATE"]
color = COLORS.get(state)
subtitle = "Service Notification"
facts.append({"name": "Service:", "value": context["SERVICEDESC"]})
output = context["SERVICEOUTPUT"] if context["SERVICEOUTPUT"] else ""
else:
state = context["HOSTSTATE"]
color = COLORS.get(state)
subtitle = "Host Notification"
output = context["HOSTOUTPUT"] if context["HOSTOUTPUT"] else ""
facts.extend([
{
"name": "Host:",
"value": context["HOSTNAME"]
},
{
"name": "State:",
"value": state
}
])
mention = f"<@&{ROLE_MENTION_ID}>"
return {
"username": USERNAME,
"avatar_url": AVATARURL,
"content": mention, # Add the role mention here
"embeds": [
{
"title": subtitle,
"color": color,
"fields": facts,
"footer": {
"text": output
}
}
]
}
# Rest of the code..
def collect_context():
return {
var[7:]: value
for (var, value) in os.environ.items()
if var.startswith("NOTIFY_")
}
def post_request(message_constructor, success_code=204):
context = collect_context()
url = context.get("PARAMETERS")
r = requests.post(url=url, json=message_constructor(context))
if r.status_code == success_code:
sys.exit(0)
else:
sys.stderr.write(
"Failed to send notification. Status: %i, Response: %s\n" % (r.status_code, r.text))
sys.exit(2)
if __name__ == "__main__":
post_request(discord_msg).
Did I get that right?
Thanks!
C
Thanks very much n00m!
I gave it a try but it errors:
2023-05-12 14:19:11 * notifying discord via xnewdiscord.py, parameters: https://discord.com/api/webhooks/example, bulk: no 2023-05-12 14:19:11 executing /omd/sites/dc1/local/share/check_mk/notifications/xnewdiscord.py 2023-05-12 14:19:11 Output: File "/omd/sites/dc1/local/share/check_mk/notifications/xnewdiscord.py", line 92 2023-05-12 14:19:11 Output: post_request(discord_msg). 2023-05-12 14:19:11 Output: ^ 2023-05-12 14:19:11 Output: SyntaxError: invalid syntax 2023-05-12 14:19:11 Plugin exited with code 1
I have the file like so:
#!/usr/bin/env python3 # n00m Notify via Discord import os import requests import sys USERNAME = "check_mk" AVATARURL = "https://checkmk.com/favicon-96x96.png" COLORS = { "CRITICAL": "15597568", "DOWN": "15597568", "WARNING": "16768256", "OK": "52224", "UP": "52224", "UNKNOWN": "13421772", "UNREACHABLE": "13421772", } # Add the role mention ID here # you could also use Variables from here https://docs.checkmk.com/latest/en/notifications.html#_environment_variables ROLE_MENTION_ID = "123example123" def discord_msg(context): """Build the message for discord""" facts = [] if context.get('WHAT', None) == "SERVICE": state = context["SERVICESTATE"] color = COLORS.get(state) subtitle = "Service Notification" facts.append({"name": "Service:", "value": context["SERVICEDESC"]}) output = context["SERVICEOUTPUT"] if context["SERVICEOUTPUT"] else "" else: state = context["HOSTSTATE"] color = COLORS.get(state) subtitle = "Host Notification" output = context["HOSTOUTPUT"] if context["HOSTOUTPUT"] else "" facts.extend([ { "name": "Host:", "value": context["HOSTNAME"] }, { "name": "State:", "value": state } ]) mention = f"<@&{ROLE_MENTION_ID}>" return { "username": USERNAME, "avatar_url": AVATARURL, "content": mention, # Add the role mention here "embeds": [ { "title": subtitle, "color": color, "fields": facts, "footer": { "text": output } } ] } # Rest of the code.. def collect_context(): return { var[7:]: value for (var, value) in os.environ.items() if var.startswith("NOTIFY_") } def post_request(message_constructor, success_code=204): context = collect_context() url = context.get("PARAMETERS") r = requests.post(url=url, json=message_constructor(context)) if r.status_code == success_code: sys.exit(0) else: sys.stderr.write( "Failed to send notification. Status: %i, Response: %s\n" % (r.status_code, r.text)) sys.exit(2) if __name__ == "__main__": post_request(discord_msg).
Did I get that right? Thanks! C
You have a full stop at the end of the code, please remove
Doh!
Would it be possible to make a switch so notifications become more condensed ?
Meaning the discord message becomes more lean and displays as following:
Service Notification: (carriage return here) Service: service name (carriage return here) Host: Hostname (carriage return here) State: State_here (carriage return here) Detail: detail msg here (carriage return here)
Why : when you have a large amount of hosts it is preferable to see the messages in a more condensed way (saves scrolling).
Hope to hear back from you :)
Also one thing i did change in the script was the value of AVATARURL.
For some reason it never took hold, and got the default 'Wumpus' avatar witth the notifications.
After some digging i changed it to : "https://checkmk.com/android-chrome-192x192.png" - which works and shows the logo of CMK as avatar.
Inspired by your plugin I also extended it a lot for my homelab an pushed all changes to a dedicated repo in case someone else wants to use it: https://github.com/fschlag/cmk_discord
Inspired by your plugin I also extended it a lot for my homelab an pushed all changes to a dedicated repo in case someone else wants to use it: https://github.com/fschlag/cmk_discord
Thanks @fschlag! Looks good and future development should and will be done in your project.
Heyho :)
Danke dir erstmal für dein Skript! Bringt mich weiter :) Jedoch hab ich gemerkt, dass das System die selbe Notification zwei mal abschickt. Hast du eine Idee was es sein könnte?
LG
Horstie