diff --git a/client/app/assets/images/destinations/hangouts_chat.png b/client/app/assets/images/destinations/hangouts_chat.png new file mode 100644 index 0000000000..ef934b0a2c Binary files /dev/null and b/client/app/assets/images/destinations/hangouts_chat.png differ diff --git a/redash/destinations/hangoutschat.py b/redash/destinations/hangoutschat.py new file mode 100644 index 0000000000..28951b6193 --- /dev/null +++ b/redash/destinations/hangoutschat.py @@ -0,0 +1,96 @@ +import logging +import requests + +from redash.destinations import * +from redash.utils import json_dumps + + +class HangoutsChat(BaseDestination): + @classmethod + def name(cls): + return "Google Hangouts Chat" + + @classmethod + def type(cls): + return "hangouts_chat" + + @classmethod + def configuration_schema(cls): + return { + "type": "object", + "properties": { + "url": { + "type": "string", + "title": "Webhook URL (get it from the room settings)" + }, + "icon_url": { + "type": "string", + "title": "Icon URL (32x32 or multiple, png format)" + } + }, + "required": ["url"] + } + + @classmethod + def icon(cls): + return 'fa-bolt' + + def notify(self, alert, query, user, new_state, app, host, options): + try: + if new_state == "triggered": + message = "Triggered" + elif new_state == "ok": + message = "Went back to normal" + else: + message = "Unable to determine status. Check Query and Alert configuration." + + data = { + "cards": [ + { + "header": { + "title": alert.name + }, + "sections": [ + { + "widgets": [ + { + "textParagraph": { + "text": message + } + } + ] + } + ] + } + ] + } + + if options.get("icon_url"): + data["cards"][0]["header"]["imageUrl"] = options.get("icon_url") + + # Hangouts Chat will create a blank card if an invalid URL (no hostname) is posted. + if host: + data["cards"][0]["sections"][0]["widgets"].append({ + "buttons": [ + { + "textButton": { + "text": "OPEN QUERY", + "onClick": { + "openLink": { + "url": "{host}/queries/{query_id}".format(host=host, query_id=query.id) + } + } + } + } + ] + }) + + headers = {"Content-Type": "application/json; charset=UTF-8"} + resp = requests.post(options.get("url"), data=json_dumps(data), headers=headers, timeout=5.0) + if resp.status_code != 200: + logging.error("webhook send ERROR. status_code => {status}".format(status=resp.status_code)) + except Exception: + logging.exception("webhook send ERROR.") + + +register(HangoutsChat) diff --git a/redash/settings/__init__.py b/redash/settings/__init__.py index 5dd7611a78..2b9e870100 100644 --- a/redash/settings/__init__.py +++ b/redash/settings/__init__.py @@ -216,6 +216,7 @@ def all_settings(): 'redash.destinations.mattermost', 'redash.destinations.chatwork', 'redash.destinations.pagerduty', + 'redash.destinations.hangoutschat' ] enabled_destinations = array_from_string(os.environ.get("REDASH_ENABLED_DESTINATIONS", ",".join(default_destinations)))