from ..core import Provider
from ..core import Response
from ..utils import requests
[docs]class Slack(Provider):
"""Send Slack webhook notifications"""
base_url = "https://hooks.slack.com/services/"
site_url = "https://api.slack.com/incoming-webhooks"
name = "slack"
__fields = {
"type": "array",
"title": "Fields are displayed in a table on the message",
"minItems": 1,
"items": {
"type": "object",
"properties": {
"title": {"type": "string", "title": "Required Field Title"},
"value": {
"type": "string",
"title": "Text value of the field. May contain standard message markup and must"
" be escaped as normal. May be multi-line",
},
"short": {
"type": "boolean",
"title": "Optional flag indicating whether the `value` is short enough to be displayed"
" side-by-side with other values",
},
},
"required": ["title"],
"additionalProperties": False,
},
}
__attachments = {
"type": "array",
"items": {
"type": "object",
"properties": {
"title": {"type": "string", "title": "Attachment title"},
"author_name": {
"type": "string",
"title": "Small text used to display the author's name",
},
"author_link": {
"type": "string",
"title": "A valid URL that will hyperlink the author_name text mentioned above. "
"Will only work if author_name is present",
},
"author_icon": {
"type": "string",
"title": "A valid URL that displays a small 16x16px image to the left of the author_name text. "
"Will only work if author_name is present",
},
"title_link": {"type": "string", "title": "Attachment title URL"},
"image_url": {"type": "string", "format": "uri", "title": "Image URL"},
"thumb_url": {
"type": "string",
"format": "uri",
"title": "Thumbnail URL",
},
"footer": {"type": "string", "title": "Footer text"},
"footer_icon": {
"type": "string",
"format": "uri",
"title": "Footer icon URL",
},
"ts": {
"type": ["integer", "string"],
"format": "timestamp",
"title": "Provided timestamp (epoch)",
},
"fallback": {
"type": "string",
"title": "A plain-text summary of the attachment. This text will be used in clients that don't"
" show formatted text (eg. IRC, mobile notifications) and should not contain any markup.",
},
"text": {
"type": "string",
"title": "Optional text that should appear within the attachment",
},
"pretext": {
"type": "string",
"title": "Optional text that should appear above the formatted data",
},
"color": {
"type": "string",
"title": "Can either be one of 'good', 'warning', 'danger', or any hex color code",
},
"fields": __fields,
},
"required": ["fallback"],
"additionalProperties": False,
},
}
_required = {"required": ["webhook_url", "message"]}
_schema = {
"type": "object",
"properties": {
"webhook_url": {
"type": "string",
"format": "uri",
"title": "the webhook URL to use. Register one at https://my.slack.com/services/new/incoming-webhook/",
},
"icon_url": {
"type": "string",
"format": "uri",
"title": "override bot icon with image URL",
},
"icon_emoji": {
"type": "string",
"title": "override bot icon with emoji name.",
},
"username": {"type": "string", "title": "override the displayed bot name"},
"channel": {
"type": "string",
"title": "override default channel or private message",
},
"unfurl_links": {
"type": "boolean",
"title": "avoid automatic attachment creation from URLs",
},
"message": {
"type": "string",
"title": "This is the text that will be posted to the channel",
},
"attachments": __attachments,
},
"additionalProperties": False,
}
def _prepare_data(self, data: dict) -> dict:
text = data.pop("message")
data["text"] = text
if data.get("icon_emoji"):
icon_emoji = data["icon_emoji"]
if not icon_emoji.startswith(":"):
icon_emoji = f":{icon_emoji}"
if not icon_emoji.endswith(":"):
icon_emoji += ":"
data["icon_emoji"] = icon_emoji
return data
def _send_notification(self, data: dict) -> Response:
url = data.pop("webhook_url")
response, errors = requests.post(url, json=data)
return self.create_response(data, response, errors)