-
-
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) |
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
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.
Perfekt, dankeschön!