Created
March 31, 2021 16:57
-
-
Save mikloslorinczi/ea6686cafc5628a9b3966367ec8961e4 to your computer and use it in GitHub Desktop.
Unified Python reporter class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
reporter.py provides a generic Reporter class, a SlackReporter and an MSTeamsReporter child classes | |
which are capable of sending messages via webhooks to channels in their respective services. | |
''' | |
import requests | |
import pymsteams | |
class SlackError(Exception): | |
pass | |
class MSTeamsError(Exception): | |
pass | |
class Reporter: | |
def __init__(self, webhook_url: str): | |
self.webhook_url = webhook_url | |
def post(self, title: str='DevOps Report', message: str='Message body', msg_type: str='info', buttons: list=[]): | |
pass | |
class SlackReporter(Reporter): | |
divider = { | |
'type': 'divider' | |
} | |
general_pic = { | |
'type': 'image', | |
'image_url': 'https://i.imgur.com/52oX1Gm.png', | |
'alt_text': 'message icon' | |
} | |
success_pic = { | |
'type': 'image', | |
'image_url': 'https://i.imgur.com/wB4IDMB.png', | |
'alt_text': 'success icon' | |
} | |
fail_pic = { | |
'type': 'image', | |
'image_url': 'https://i.imgur.com/29VM8ef.png', | |
'alt_text': 'fail icon' | |
} | |
picture_types = { | |
'ok': success_pic, | |
'success': success_pic, | |
'fail': fail_pic, | |
'error': fail_pic, | |
} | |
def __init__(self, webhook_url: str): | |
super().__init__(webhook_url) | |
def post(self, title: str, message: str, msg_type: str, buttons: list): | |
post_data = { | |
'blocks' : [ | |
self.header(title), | |
self.text_with_pic(message, self.get_pic(msg_type)), | |
] | |
} | |
for button in buttons: | |
post_data['blocks'].extend([ | |
self.divider, | |
self.button_with_link( | |
message = button['message'], | |
button_text = button['button_text'], | |
link = button['link'])]) | |
self.__post_message(post_data) | |
def __post_message(self, post_data: dict): | |
try: | |
response = requests.post(self.webhook_url, json=post_data, headers={'content-type':'application/json'}) | |
except Exception as err: | |
raise SlackError(f'Failed to send Slack message. Error: {err}') | |
if response.status_code != 200: | |
raise SlackError(f'Non-200 Slack status: {response.status_code} response: {response.text}') | |
return True | |
@classmethod | |
def get_pic(cls, pic_type: str): | |
lower = pic_type.lower() | |
if not lower in cls.picture_types: | |
return cls.general_pic | |
return cls.picture_types[lower] | |
@staticmethod | |
def header(title: str): | |
return { | |
'type': 'header', | |
'text': { | |
'type': 'plain_text', | |
'text': title, | |
'emoji': True | |
} | |
} | |
@staticmethod | |
def text_with_pic(text: str, pic: dict): | |
return { | |
'type': 'section', | |
'text': { | |
'type': 'mrkdwn', | |
'text': text, | |
}, | |
'accessory': pic, | |
} | |
@staticmethod | |
def button_with_link(message: str, button_text: str, link: str): | |
return { | |
'type': 'section', | |
'text': { | |
'type': 'mrkdwn', | |
'text': message, | |
}, | |
'accessory': { | |
'type': 'button', | |
'text': { | |
'type': 'plain_text', | |
'text': button_text, | |
'emoji': True | |
}, | |
'value': 'click_me', | |
'url': link, | |
'action_id': 'button-action' | |
} | |
} | |
class MSTeamsReporter(Reporter): | |
# Blue | |
general_color = '#308edb' | |
# Green | |
success_color = '#4aed5f' | |
# Red | |
fail_color = '#e32e12' | |
color_types = { | |
'ok': success_color, | |
'success': success_color, | |
'fail': fail_color, | |
'error': fail_color, | |
} | |
def __init__(self, webhook_url: str): | |
super().__init__(webhook_url) | |
@classmethod | |
def get_color(cls, color_type: str): | |
lower = color_type.lower() | |
if not lower in cls.color_types: | |
return cls.general_color | |
return cls.color_types[lower] | |
def post(self, title: str, message: str, msg_type: str, buttons: list): | |
msg = pymsteams.connectorcard(self.webhook_url) | |
msg.title(title) | |
msg.text(message) | |
msg.color(self.get_color(msg_type)) | |
for button in buttons: | |
section = pymsteams.cardsection() | |
section.title(button['message']) | |
section.linkButton(button['button_text'], button['link']) | |
msg.addSection(section) | |
try: | |
msg.send() | |
except Exception as err: | |
raise MSTeamsError(f'Failed to send MS Teams message: {err}') | |
return True |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment