From a3ba8b9efdaa44c2bcd0ebcdc90500c6a3ea46d9 Mon Sep 17 00:00:00 2001 From: Adam Birds Date: Thu, 15 Apr 2021 21:39:16 +0000 Subject: [PATCH] integrations: Add Freshping webhook integration. I have added a webhook integration for Freshping. --- .../integrations/bot_avatars/freshping.png | Bin 0 -> 4773 bytes static/images/integrations/freshping/001.png | Bin 0 -> 35887 bytes .../images/integrations/logos/freshping.svg | 1 + zerver/lib/integrations.py | 2 + zerver/webhooks/freshping/__init__.py | 0 zerver/webhooks/freshping/doc.md | 18 ++++++ .../fixtures/freshping_check_reachable.json | 26 +++++++++ .../fixtures/freshping_check_test.json | 24 ++++++++ .../fixtures/freshping_check_unreachable.json | 26 +++++++++ zerver/webhooks/freshping/tests.py | 34 +++++++++++ zerver/webhooks/freshping/view.py | 55 ++++++++++++++++++ 11 files changed, 186 insertions(+) create mode 100644 static/images/integrations/bot_avatars/freshping.png create mode 100644 static/images/integrations/freshping/001.png create mode 100644 static/images/integrations/logos/freshping.svg create mode 100644 zerver/webhooks/freshping/__init__.py create mode 100644 zerver/webhooks/freshping/doc.md create mode 100644 zerver/webhooks/freshping/fixtures/freshping_check_reachable.json create mode 100644 zerver/webhooks/freshping/fixtures/freshping_check_test.json create mode 100644 zerver/webhooks/freshping/fixtures/freshping_check_unreachable.json create mode 100644 zerver/webhooks/freshping/tests.py create mode 100644 zerver/webhooks/freshping/view.py diff --git a/static/images/integrations/bot_avatars/freshping.png b/static/images/integrations/bot_avatars/freshping.png new file mode 100644 index 0000000000000000000000000000000000000000..c7d9779e53998c31b5c8c60c4c29584e75625f48 GIT binary patch literal 4773 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 literal 0 HcmV?d00001 diff --git a/static/images/integrations/freshping/001.png b/static/images/integrations/freshping/001.png new file mode 100644 index 0000000000000000000000000000000000000000..e0a02491a875feff68dc793b868e4babe6a534a7 GIT binary patch literal 35887 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 literal 0 HcmV?d00001 diff --git a/static/images/integrations/logos/freshping.svg b/static/images/integrations/logos/freshping.svg new file mode 100644 index 0000000000..d375538db4 --- /dev/null +++ b/static/images/integrations/logos/freshping.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/zerver/lib/integrations.py b/zerver/lib/integrations.py index 1188649d02..451fff0554 100644 --- a/zerver/lib/integrations.py +++ b/zerver/lib/integrations.py @@ -373,6 +373,7 @@ WEBHOOK_INTEGRATIONS: List[WebhookIntegration] = [ WebhookIntegration("errbit", ["monitoring"], display_name="Errbit"), WebhookIntegration("flock", ["customer-support"], display_name="Flock"), WebhookIntegration("freshdesk", ["customer-support"]), + WebhookIntegration("freshping", ["monitoring"], display_name="Freshping"), WebhookIntegration("front", ["customer-support"], display_name="Front"), WebhookIntegration("gitea", ["version-control"], stream_name="commits"), WebhookIntegration( @@ -712,6 +713,7 @@ DOC_SCREENSHOT_CONFIG: Dict[str, List[BaseScreenshotConfig]] = { "freshdesk": [ ScreenshotConfig("ticket_created.json", image_name="004.png", use_basic_auth=True) ], + "freshping": [ScreenshotConfig("freshping_check_unreachable.json")], "front": [ScreenshotConfig("inbound_message.json")], "gci": [ScreenshotConfig("task_abandoned_by_student.json")], "gitea": [ScreenshotConfig("pull_request__merged.json")], diff --git a/zerver/webhooks/freshping/__init__.py b/zerver/webhooks/freshping/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/zerver/webhooks/freshping/doc.md b/zerver/webhooks/freshping/doc.md new file mode 100644 index 0000000000..57f0305c8e --- /dev/null +++ b/zerver/webhooks/freshping/doc.md @@ -0,0 +1,18 @@ +Receive Freshping notifications in Zulip! + +1. {!create-stream.md!} + +1. {!create-bot-construct-url-indented.md!} + +1. Go to your **Freshping** dashboard and click **Settings**. + Click **Integrations** and then click **Create Integration** + under **Webhooks**. + +1. Set **Domain URL** to the URL create above. Click **Create**. + +1. You can test the webhook by clicking **Test** to ensure it is + configured correctly. + +{!congrats.md!} + +![](/static/images/integrations/freshping/001.png) diff --git a/zerver/webhooks/freshping/fixtures/freshping_check_reachable.json b/zerver/webhooks/freshping/fixtures/freshping_check_reachable.json new file mode 100644 index 0000000000..cf01fda6ce --- /dev/null +++ b/zerver/webhooks/freshping/fixtures/freshping_check_reachable.json @@ -0,0 +1,26 @@ +{ + "organization_name": "Example Org", + "webhook_event_id": 5301955, + "organization_id": 156000, + "webhook_type": "AL", + "webhook_event_data": { + "check_state_name": "Available", + "check_computed_target_response_time": 1000, + "application_id": 155565, + "recently_started_check_state_name": null, + "check_id": 585767, + "recently_started_check_start_time": null, + "http_status_code": 200, + "request_start_time": "2021-04-15T19:57:32.607484+00:00", + "check_name": "Test Check", + "recently_started_check_http_status_code": null, + "application_name": " 's Application", + "recently_started_check_response_time": null, + "request_url": "https://example.com", + "check_target_response_time": 1000, + "@type": "MessageCard", + "response_time": 140 + }, + "webhook_id": 24172, + "webhook_event_created_on": "2021-04-15T19:57:33.035824+00:00" +} diff --git a/zerver/webhooks/freshping/fixtures/freshping_check_test.json b/zerver/webhooks/freshping/fixtures/freshping_check_test.json new file mode 100644 index 0000000000..2294db608d --- /dev/null +++ b/zerver/webhooks/freshping/fixtures/freshping_check_test.json @@ -0,0 +1,24 @@ +{ + "organization_name": "Example Org", + "webhook_event_id": 5301811, + "organization_id": 156000, + "webhook_type": "AL", + "webhook_event_data": { + "check_state_name": "Available", + "check_target_response_time": 100, + "recently_started_check_state_name": null, + "check_id": 1, + "recently_started_check_start_time": null, + "http_status_code": 200, + "request_start_time": "2021-04-15T19:36:31.812658+00:00", + "check_name": "Example check", + "recently_started_check_http_status_code": null, + "application_name": "Webhook test", + "recently_started_check_response_time": null, + "request_url": "https://www.example.com/", + "check_computed_target_response_time": 200, + "response_time": 50 + }, + "webhook_id": 24172, + "webhook_event_created_on": "2021-04-15T19:36:31.812999+00:00" +} diff --git a/zerver/webhooks/freshping/fixtures/freshping_check_unreachable.json b/zerver/webhooks/freshping/fixtures/freshping_check_unreachable.json new file mode 100644 index 0000000000..8cda6c9067 --- /dev/null +++ b/zerver/webhooks/freshping/fixtures/freshping_check_unreachable.json @@ -0,0 +1,26 @@ +{ + "organization_name": "Example Org", + "webhook_event_id": 5301855, + "organization_id": 156000, + "webhook_type": "AL", + "webhook_event_data": { + "check_state_name": "Reporting Error", + "check_computed_target_response_time": 1000, + "application_id": 155565, + "recently_started_check_state_name": null, + "check_id": 585767, + "recently_started_check_start_time": null, + "http_status_code": 521, + "request_start_time": "2021-04-15T19:46:47.644166+00:00", + "check_name": "Test Check", + "recently_started_check_http_status_code": null, + "application_name": " 's Application", + "recently_started_check_response_time": null, + "request_url": "https://example.com", + "check_target_response_time": 1000, + "@type": "MessageCard", + "response_time": 635 + }, + "webhook_id": 24172, + "webhook_event_created_on": "2021-04-15T19:46:49.077370+00:00" +} diff --git a/zerver/webhooks/freshping/tests.py b/zerver/webhooks/freshping/tests.py new file mode 100644 index 0000000000..e8e92847a4 --- /dev/null +++ b/zerver/webhooks/freshping/tests.py @@ -0,0 +1,34 @@ +from zerver.lib.test_classes import WebhookTestCase + + +class FreshpingHookTests(WebhookTestCase): + STREAM_NAME = "freshping" + URL_TEMPLATE = "/api/v1/external/freshping?api_key={api_key}&stream={stream}" + FIXTURE_DIR_NAME = "freshping" + + def test_freshping_check_test(self) -> None: + """ + Tests if freshping check test is handled correctly + """ + expected_topic = "Freshping" + expected_message = "Freshping webhook has been successfully configured." + self.check_webhook("freshping_check_test", expected_topic, expected_message) + + def test_freshping_check_unreachable(self) -> None: + """ + Tests if freshping check unreachable is handled correctly + """ + expected_topic = "Test Check" + expected_message = """ +https://example.com has just become unreachable. +Error Code: 521. +""".strip() + self.check_webhook("freshping_check_unreachable", expected_topic, expected_message) + + def test_freshping_check_reachable(self) -> None: + """ + Tests if freshping check reachable is handled correctly + """ + expected_topic = "Test Check" + expected_message = "https://example.com is back up and no longer unreachable." + self.check_webhook("freshping_check_reachable", expected_topic, expected_message) diff --git a/zerver/webhooks/freshping/view.py b/zerver/webhooks/freshping/view.py new file mode 100644 index 0000000000..c5a59ecf73 --- /dev/null +++ b/zerver/webhooks/freshping/view.py @@ -0,0 +1,55 @@ +from typing import Any, Dict + +from django.http import HttpRequest, HttpResponse + +from zerver.decorator import REQ, has_request_variables, webhook_view +from zerver.lib.response import json_success +from zerver.lib.webhooks.common import check_send_webhook_message, get_setup_webhook_message +from zerver.models import UserProfile + +FRESHPING_TOPIC_TEMPLATE_TEST = "Freshping" +FRESHPING_TOPIC_TEMPLATE = "{check_name}" + +FRESHPING_MESSAGE_TEMPLATE_UNREACHABLE = """ +{request_url} has just become unreachable. +Error Code: {http_status_code}. +""".strip() +FRESHPING_MESSAGE_TEMPLATE_UP = "{request_url} is back up and no longer unreachable." + + +@webhook_view("Freshping") +@has_request_variables +def api_freshping_webhook( + request: HttpRequest, + user_profile: UserProfile, + payload: Dict[str, Any] = REQ(argument_type="body"), +) -> HttpResponse: + + body = get_body_for_http_request(payload) + subject = get_subject_for_http_request(payload) + + check_send_webhook_message(request, user_profile, subject, body) + return json_success() + + +def get_subject_for_http_request(payload: Dict[str, Any]) -> str: + webhook_event_data = payload["webhook_event_data"] + if webhook_event_data["application_name"] == "Webhook test": + subject = FRESHPING_TOPIC_TEMPLATE_TEST + else: + subject = FRESHPING_TOPIC_TEMPLATE.format(check_name=webhook_event_data["check_name"]) + + return subject + + +def get_body_for_http_request(payload: Dict[str, Any]) -> str: + webhook_event_data = payload["webhook_event_data"] + if webhook_event_data["check_state_name"] == "Reporting Error": + body = FRESHPING_MESSAGE_TEMPLATE_UNREACHABLE.format(**webhook_event_data) + elif webhook_event_data["check_state_name"] == "Available": + if webhook_event_data["application_name"] == "Webhook test": + body = get_setup_webhook_message("Freshping") + else: + body = FRESHPING_MESSAGE_TEMPLATE_UP.format(**webhook_event_data) + + return body