mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-03 21:43:21 +00:00 
			
		
		
		
	Add updownio integration.
This commit is contained in:
		
							
								
								
									
										
											BIN
										
									
								
								static/images/integrations/logos/updown.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/images/integrations/logos/updown.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 3.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								static/images/integrations/updown/001.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/images/integrations/updown/001.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 23 KiB  | 
@@ -280,6 +280,12 @@
 | 
				
			|||||||
            <span class="integration-label">Twitter</span>
 | 
					            <span class="integration-label">Twitter</span>
 | 
				
			||||||
         </a>
 | 
					         </a>
 | 
				
			||||||
       </div>
 | 
					       </div>
 | 
				
			||||||
 | 
					       <div class="integration-lozenge integration-updown">
 | 
				
			||||||
 | 
					         <a class="integration-link integration-updown" href="#updown">
 | 
				
			||||||
 | 
					            <img class="integration-logo" src="/static/images/integrations/logos/updown.png" alt="Updown logo" />
 | 
				
			||||||
 | 
					            <span class="integration-label">Updown</span>
 | 
				
			||||||
 | 
					         </a>
 | 
				
			||||||
 | 
					       </div>
 | 
				
			||||||
       <div class="integration-lozenge integration-yo-app">
 | 
					       <div class="integration-lozenge integration-yo-app">
 | 
				
			||||||
         <a class="integration-link integration-yo-app" href="#yo-app">
 | 
					         <a class="integration-link integration-yo-app" href="#yo-app">
 | 
				
			||||||
            <img class="integration-logo" src="/static/images/integrations/logos/yo-app.png" alt="Yo App logo" />
 | 
					            <img class="integration-logo" src="/static/images/integrations/logos/yo-app.png" alt="Yo App logo" />
 | 
				
			||||||
@@ -2155,6 +2161,32 @@ access_token_secret =</pre>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <div id="updown" class="integration-instructions">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <p>See Updown reports in Zulip! This is great to be up to date with
 | 
				
			||||||
 | 
					      downtime in the services you monitor with Updown!
 | 
				
			||||||
 | 
					      </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <p>First, create the stream you'd like to use for updown
 | 
				
			||||||
 | 
					      notifications, and subscribe all interested parties to this
 | 
				
			||||||
 | 
					      stream. We recommend the name <code>updown</code>.</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <p>Go to <a href="https://updown.io/settings/edit">your Updown
 | 
				
			||||||
 | 
					      settings page</a> and in <code>WEBHOOKS</code> section, enter
 | 
				
			||||||
 | 
					      the following as the URL:</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <p><code>{{ external_api_uri }}/v1/external/updown?api_key=abcdefgh&stream=updown</code></p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <p><b>Congratulations! You're done!</b><br />
 | 
				
			||||||
 | 
					          Now you'll receive Updown notifications for your service in Zulip.
 | 
				
			||||||
 | 
					      </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <img class="screenshot" src="/static/images/integrations/updown/001.png" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <div id="yo-app" class="integration-instructions">
 | 
					    <div id="yo-app" class="integration-instructions">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      <p>See your Yo App notifications in Zulip!</p>
 | 
					      <p>See your Yo App notifications in Zulip!</p>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										27
									
								
								zerver/fixtures/updown/updown_check_down_one_event.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								zerver/fixtures/updown/updown_check_down_one_event.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					[{
 | 
				
			||||||
 | 
					  "event": "check.down",
 | 
				
			||||||
 | 
					  "check": {
 | 
				
			||||||
 | 
					    "token": "ngg8",
 | 
				
			||||||
 | 
					    "url": "https://updown.io",
 | 
				
			||||||
 | 
					    "alias": "",
 | 
				
			||||||
 | 
					    "last_status": 500,
 | 
				
			||||||
 | 
					    "uptime": 100.0,
 | 
				
			||||||
 | 
					    "down": true,
 | 
				
			||||||
 | 
					    "down_since": "2016-02-07T13:11:43Z",
 | 
				
			||||||
 | 
					    "error": "500",
 | 
				
			||||||
 | 
					    "period": 30,
 | 
				
			||||||
 | 
					    "apdex_t": 0.25,
 | 
				
			||||||
 | 
					    "string_match": "",
 | 
				
			||||||
 | 
					    "enabled": true,
 | 
				
			||||||
 | 
					    "published": true,
 | 
				
			||||||
 | 
					    "last_check_at": "2016-02-07T13:12:13Z",
 | 
				
			||||||
 | 
					    "next_check_at": "2016-02-07T13:12:43Z",
 | 
				
			||||||
 | 
					    "favicon_url": "https://updown.io/favicon.png"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "downtime": {
 | 
				
			||||||
 | 
					    "error": "500",
 | 
				
			||||||
 | 
					    "started_at": "2016-02-07T13:11:43Z",
 | 
				
			||||||
 | 
					    "ended_at": null,
 | 
				
			||||||
 | 
					    "duration": null
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}]
 | 
				
			||||||
							
								
								
									
										56
									
								
								zerver/fixtures/updown/updown_check_multiple_events.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								zerver/fixtures/updown/updown_check_multiple_events.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					[
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "event": "check.down",
 | 
				
			||||||
 | 
					    "check": {
 | 
				
			||||||
 | 
					      "token": "ngg8",
 | 
				
			||||||
 | 
					      "url": "https://updown.io",
 | 
				
			||||||
 | 
					      "alias": "",
 | 
				
			||||||
 | 
					      "last_status": 200,
 | 
				
			||||||
 | 
					      "uptime": 99.954,
 | 
				
			||||||
 | 
					      "down": false,
 | 
				
			||||||
 | 
					      "down_since": null,
 | 
				
			||||||
 | 
					      "error": null,
 | 
				
			||||||
 | 
					      "period": 30,
 | 
				
			||||||
 | 
					      "apdex_t": 0.25,
 | 
				
			||||||
 | 
					      "string_match": "",
 | 
				
			||||||
 | 
					      "enabled": true,
 | 
				
			||||||
 | 
					      "published": true,
 | 
				
			||||||
 | 
					      "last_check_at": "2016-02-07T13:16:07Z",
 | 
				
			||||||
 | 
					      "next_check_at": "2016-02-07T13:16:37Z",
 | 
				
			||||||
 | 
					      "favicon_url": "https://updown.io/favicon.png"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "downtime": {
 | 
				
			||||||
 | 
					      "error": "500",
 | 
				
			||||||
 | 
					      "started_at": "2016-02-07T13:11:43Z",
 | 
				
			||||||
 | 
					      "ended_at": null,
 | 
				
			||||||
 | 
					      "duration": null
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "event": "check.up",
 | 
				
			||||||
 | 
					    "check": {
 | 
				
			||||||
 | 
					      "token": "ngg8",
 | 
				
			||||||
 | 
					      "url": "https://updown.io",
 | 
				
			||||||
 | 
					      "alias": "",
 | 
				
			||||||
 | 
					      "last_status": 200,
 | 
				
			||||||
 | 
					      "uptime": 99.954,
 | 
				
			||||||
 | 
					      "down": false,
 | 
				
			||||||
 | 
					      "down_since": null,
 | 
				
			||||||
 | 
					      "error": null,
 | 
				
			||||||
 | 
					      "period": 30,
 | 
				
			||||||
 | 
					      "apdex_t": 0.25,
 | 
				
			||||||
 | 
					      "string_match": "",
 | 
				
			||||||
 | 
					      "enabled": true,
 | 
				
			||||||
 | 
					      "published": true,
 | 
				
			||||||
 | 
					      "last_check_at": "2016-02-07T13:16:07Z",
 | 
				
			||||||
 | 
					      "next_check_at": "2016-02-07T13:16:37Z",
 | 
				
			||||||
 | 
					      "favicon_url": "https://updown2.io/favicon.png"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "downtime": {
 | 
				
			||||||
 | 
					      "error": "500",
 | 
				
			||||||
 | 
					      "started_at": "2016-02-07T13:11:43Z",
 | 
				
			||||||
 | 
					      "ended_at": "2016-02-07T13:11:44Z",
 | 
				
			||||||
 | 
					      "duration": 1
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
							
								
								
									
										27
									
								
								zerver/fixtures/updown/updown_check_up_again_one_event.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								zerver/fixtures/updown/updown_check_up_again_one_event.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					[{
 | 
				
			||||||
 | 
					  "event": "check.up",
 | 
				
			||||||
 | 
					  "check": {
 | 
				
			||||||
 | 
					    "token": "ngg8",
 | 
				
			||||||
 | 
					    "url": "https://updown.io",
 | 
				
			||||||
 | 
					    "alias": "",
 | 
				
			||||||
 | 
					    "last_status": 200,
 | 
				
			||||||
 | 
					    "uptime": 99.954,
 | 
				
			||||||
 | 
					    "down": false,
 | 
				
			||||||
 | 
					    "down_since": null,
 | 
				
			||||||
 | 
					    "error": null,
 | 
				
			||||||
 | 
					    "period": 30,
 | 
				
			||||||
 | 
					    "apdex_t": 0.25,
 | 
				
			||||||
 | 
					    "string_match": "",
 | 
				
			||||||
 | 
					    "enabled": true,
 | 
				
			||||||
 | 
					    "published": true,
 | 
				
			||||||
 | 
					    "last_check_at": "2016-02-07T13:16:07Z",
 | 
				
			||||||
 | 
					    "next_check_at": "2016-02-07T13:16:37Z",
 | 
				
			||||||
 | 
					    "favicon_url": "https://updown.io/favicon.png"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "downtime": {
 | 
				
			||||||
 | 
					    "error": "500",
 | 
				
			||||||
 | 
					    "started_at": "2016-02-07T13:11:43Z",
 | 
				
			||||||
 | 
					    "ended_at": "2016-02-07T13:16:07Z",
 | 
				
			||||||
 | 
					    "duration": 265
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}]
 | 
				
			||||||
							
								
								
									
										27
									
								
								zerver/fixtures/updown/updown_check_up_first_time.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								zerver/fixtures/updown/updown_check_up_first_time.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					[{
 | 
				
			||||||
 | 
					  "event": "check.up",
 | 
				
			||||||
 | 
					  "check": {
 | 
				
			||||||
 | 
					    "token": "ngg8",
 | 
				
			||||||
 | 
					    "url": "https://updown.io",
 | 
				
			||||||
 | 
					    "alias": "",
 | 
				
			||||||
 | 
					    "last_status": 200,
 | 
				
			||||||
 | 
					    "uptime": 99.954,
 | 
				
			||||||
 | 
					    "down": false,
 | 
				
			||||||
 | 
					    "down_since": null,
 | 
				
			||||||
 | 
					    "error": null,
 | 
				
			||||||
 | 
					    "period": 30,
 | 
				
			||||||
 | 
					    "apdex_t": 0.25,
 | 
				
			||||||
 | 
					    "string_match": "",
 | 
				
			||||||
 | 
					    "enabled": true,
 | 
				
			||||||
 | 
					    "published": true,
 | 
				
			||||||
 | 
					    "last_check_at": "2016-02-07T13:16:07Z",
 | 
				
			||||||
 | 
					    "next_check_at": "2016-02-07T13:16:37Z",
 | 
				
			||||||
 | 
					    "favicon_url": "https://updown.io/favicon.png"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "downtime": {
 | 
				
			||||||
 | 
					    "error": null,
 | 
				
			||||||
 | 
					    "started_at": null,
 | 
				
			||||||
 | 
					    "ended_at": null,
 | 
				
			||||||
 | 
					    "duration": null
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}]
 | 
				
			||||||
@@ -416,6 +416,9 @@ class AuthedTestCase(TestCase):
 | 
				
			|||||||
        # type: () -> Message
 | 
					        # type: () -> Message
 | 
				
			||||||
        return Message.objects.latest('id')
 | 
					        return Message.objects.latest('id')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_second_to_last_message(self):
 | 
				
			||||||
 | 
					        return Message.objects.all().order_by('-id')[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_all_templates():
 | 
					def get_all_templates():
 | 
				
			||||||
    # type: () -> List[str]
 | 
					    # type: () -> List[str]
 | 
				
			||||||
    templates = []
 | 
					    templates = []
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1244,3 +1244,39 @@ class AirbrakeHookTests(WebhookTestCase):
 | 
				
			|||||||
        expected_subject = u"ZulipIntegrationTest"
 | 
					        expected_subject = u"ZulipIntegrationTest"
 | 
				
			||||||
        expected_message = u"[ZeroDivisionError](https://zulip.airbrake.io/projects/125209/groups/1705190192091077626): \"Error message from logger\" occurred."
 | 
					        expected_message = u"[ZeroDivisionError](https://zulip.airbrake.io/projects/125209/groups/1705190192091077626): \"Error message from logger\" occurred."
 | 
				
			||||||
        self.send_and_test_stream_message('error_message', expected_subject, expected_message)
 | 
					        self.send_and_test_stream_message('error_message', expected_subject, expected_message)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class UpdownHookTests(WebhookTestCase):
 | 
				
			||||||
 | 
					    STREAM_NAME = 'updown'
 | 
				
			||||||
 | 
					    URL_TEMPLATE = "/api/v1/external/updown?stream={stream}&api_key={api_key}"
 | 
				
			||||||
 | 
					    FIXTURE_DIR_NAME = 'updown'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_updown_check_down_event(self):
 | 
				
			||||||
 | 
					        expected_subject = u"https://updown.io"
 | 
				
			||||||
 | 
					        expected_message = u"Service is `down`. It returned \"500\" error at 07-02-2016 13:11."
 | 
				
			||||||
 | 
					        self.send_and_test_stream_message('check_down_one_event', expected_subject, expected_message)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_updown_check_up_again_event(self):
 | 
				
			||||||
 | 
					        expected_subject = u"https://updown.io"
 | 
				
			||||||
 | 
					        expected_message = u"Service is `up` again after 4 minutes 25 seconds."
 | 
				
			||||||
 | 
					        self.send_and_test_stream_message('check_up_again_one_event', expected_subject, expected_message)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_updown_check_up_event(self):
 | 
				
			||||||
 | 
					        expected_subject = u"https://updown.io"
 | 
				
			||||||
 | 
					        expected_message = u"Service is `up`."
 | 
				
			||||||
 | 
					        self.send_and_test_stream_message('check_up_first_time', expected_subject, expected_message)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_updown_check_up_multiple_events(self):
 | 
				
			||||||
 | 
					        first_message_expected_subject = u"https://updown.io"
 | 
				
			||||||
 | 
					        first_message_expected_message = u"Service is `up` again after 1 second."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        second_message_expected_subject = u"https://updown.io"
 | 
				
			||||||
 | 
					        second_message_expected_message = u"Service is `down`. It returned \"500\" error at 07-02-2016 13:11."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.send_and_test_stream_message('check_multiple_events')
 | 
				
			||||||
 | 
					        last_message = self.get_last_message()
 | 
				
			||||||
 | 
					        self.do_test_subject(last_message, first_message_expected_subject)
 | 
				
			||||||
 | 
					        self.do_test_message(last_message, first_message_expected_message)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        second_to_last_message = self.get_second_to_last_message()
 | 
				
			||||||
 | 
					        self.do_test_subject(second_to_last_message, second_message_expected_subject)
 | 
				
			||||||
 | 
					        self.do_test_message(second_to_last_message, second_message_expected_message)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										94
									
								
								zerver/views/webhooks/updown.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								zerver/views/webhooks/updown.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,94 @@
 | 
				
			|||||||
 | 
					# Webhooks for external integrations.
 | 
				
			||||||
 | 
					from __future__ import absolute_import
 | 
				
			||||||
 | 
					import re
 | 
				
			||||||
 | 
					from datetime import datetime
 | 
				
			||||||
 | 
					from typing import Any, Dict
 | 
				
			||||||
 | 
					from django.http import HttpRequest, HttpResponse
 | 
				
			||||||
 | 
					from django.utils.translation import ugettext as _
 | 
				
			||||||
 | 
					from zerver.lib.actions import check_send_message
 | 
				
			||||||
 | 
					from zerver.lib.response import json_success, json_error
 | 
				
			||||||
 | 
					from zerver.lib.request import JsonableError
 | 
				
			||||||
 | 
					from zerver.decorator import REQ, has_request_variables, api_key_only_webhook_view
 | 
				
			||||||
 | 
					from zerver.models import UserProfile, Client
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SUBJECT_TEMPLATE = "{service_url}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class UnsupportedUpdownEventType(JsonableError):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def send_message_for_event(event, user_profile, client, stream):
 | 
				
			||||||
 | 
					    # type: (Dict[str, Any], UserProfile, Client, str) -> None
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        event_type = get_event_type(event)
 | 
				
			||||||
 | 
					        subject = SUBJECT_TEMPLATE.format(service_url=event['check']['url'])
 | 
				
			||||||
 | 
					        body = EVENT_TYPE_BODY_MAPPER[event_type](event)
 | 
				
			||||||
 | 
					    except KeyError as e:
 | 
				
			||||||
 | 
					        return json_error(_("Missing key {} in JSON").format(e.message))
 | 
				
			||||||
 | 
					    check_send_message(user_profile, client, 'stream', [stream], subject, body)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_body_for_up_event(event):
 | 
				
			||||||
 | 
					    # type: (Dict[str, Any]) -> str
 | 
				
			||||||
 | 
					    body = "Service is `up`"
 | 
				
			||||||
 | 
					    event_downtime = event['downtime']
 | 
				
			||||||
 | 
					    if event_downtime['started_at']:
 | 
				
			||||||
 | 
					        body = "{} again".format(body)
 | 
				
			||||||
 | 
					        string_date = get_time_string_based_on_duration(event_downtime['duration'])
 | 
				
			||||||
 | 
					        if string_date:
 | 
				
			||||||
 | 
					            body = "{} after {}".format(body, string_date)
 | 
				
			||||||
 | 
					    return "{}.".format(body)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_time_string_based_on_duration(duration):
 | 
				
			||||||
 | 
					    # type: (int) -> str
 | 
				
			||||||
 | 
					    days, reminder = divmod(duration, 86400)
 | 
				
			||||||
 | 
					    hours, reminder = divmod(reminder, 3600)
 | 
				
			||||||
 | 
					    minutes, seconds = divmod(reminder, 60)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    string_date = ''
 | 
				
			||||||
 | 
					    string_date += add_time_part_to_string_date_if_needed(days, 'day')
 | 
				
			||||||
 | 
					    string_date += add_time_part_to_string_date_if_needed(hours, 'hour')
 | 
				
			||||||
 | 
					    string_date += add_time_part_to_string_date_if_needed(minutes, 'minute')
 | 
				
			||||||
 | 
					    string_date += add_time_part_to_string_date_if_needed(seconds, 'second')
 | 
				
			||||||
 | 
					    return string_date.rstrip()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def add_time_part_to_string_date_if_needed(value, text_name):
 | 
				
			||||||
 | 
					    # type: (int, str) -> str
 | 
				
			||||||
 | 
					    if value == 1:
 | 
				
			||||||
 | 
					        return "1 {} ".format(text_name)
 | 
				
			||||||
 | 
					    if value > 1:
 | 
				
			||||||
 | 
					        return "{} {}s ".format(value, text_name)
 | 
				
			||||||
 | 
					    return ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_body_for_down_event(event):
 | 
				
			||||||
 | 
					    # type: (Dict[str, Any]) -> str
 | 
				
			||||||
 | 
					    event_downtime = event['downtime']
 | 
				
			||||||
 | 
					    started_at = datetime.strptime(event_downtime['started_at'], "%Y-%m-%dT%H:%M:%SZ")
 | 
				
			||||||
 | 
					    return "Service is `down`. It returned \"{}\" error at {}.".format(
 | 
				
			||||||
 | 
					        event_downtime['error'],
 | 
				
			||||||
 | 
					        started_at.strftime("%d-%m-%Y %H:%M")
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@api_key_only_webhook_view('Updown')
 | 
				
			||||||
 | 
					@has_request_variables
 | 
				
			||||||
 | 
					def api_updown_webhook(request, user_profile, client,
 | 
				
			||||||
 | 
					                       payload=REQ(argument_type='body'),
 | 
				
			||||||
 | 
					                       stream=REQ(default='updown')):
 | 
				
			||||||
 | 
					    # type: (HttpRequest, UserProfile, Client, List[Dict[str, Any]], str) -> HttpResponse
 | 
				
			||||||
 | 
					    for event in payload:
 | 
				
			||||||
 | 
					        send_message_for_event(event, user_profile, client, stream)
 | 
				
			||||||
 | 
					    return json_success()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EVENT_TYPE_BODY_MAPPER = {
 | 
				
			||||||
 | 
					    'up': get_body_for_up_event,
 | 
				
			||||||
 | 
					    'down': get_body_for_down_event
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_event_type(event):
 | 
				
			||||||
 | 
					    # type: (Dict[str, Any]) -> str
 | 
				
			||||||
 | 
					    event_type_match = re.match('check.(.*)', event['event'])
 | 
				
			||||||
 | 
					    if event_type_match:
 | 
				
			||||||
 | 
					        event_type = event_type_match.group(1)
 | 
				
			||||||
 | 
					        if event_type in EVENT_TYPE_BODY_MAPPER:
 | 
				
			||||||
 | 
					            return event_type
 | 
				
			||||||
 | 
					    raise UnsupportedUpdownEventType(event['event'])
 | 
				
			||||||
@@ -163,6 +163,7 @@ urlpatterns += patterns('zerver.views',
 | 
				
			|||||||
    url(r'^api/v1/external/teamcity$',      'webhooks.teamcity.api_teamcity_webhook'),
 | 
					    url(r'^api/v1/external/teamcity$',      'webhooks.teamcity.api_teamcity_webhook'),
 | 
				
			||||||
    url(r'^api/v1/external/transifex$',     'webhooks.transifex.api_transifex_webhook'),
 | 
					    url(r'^api/v1/external/transifex$',     'webhooks.transifex.api_transifex_webhook'),
 | 
				
			||||||
    url(r'^api/v1/external/travis$',        'webhooks.travis.api_travis_webhook'),
 | 
					    url(r'^api/v1/external/travis$',        'webhooks.travis.api_travis_webhook'),
 | 
				
			||||||
 | 
					    url(r'^api/v1/external/updown$',        'webhooks.updown.api_updown_webhook'),
 | 
				
			||||||
    url(r'^api/v1/external/yo$',            'webhooks.yo.api_yo_app_webhook'),
 | 
					    url(r'^api/v1/external/yo$',            'webhooks.yo.api_yo_app_webhook'),
 | 
				
			||||||
    url(r'^api/v1/external/zendesk$',       'webhooks.zendesk.api_zendesk_webhook'),
 | 
					    url(r'^api/v1/external/zendesk$',       'webhooks.zendesk.api_zendesk_webhook'),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user