##// END OF EJS Templates
integrations: add webhook integration
dan -
r444:3db70ed6 default
parent child Browse files
Show More
@@ -0,0 +1,106 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2012-2016 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21 from __future__ import unicode_literals
22
23 import logging
24 import requests
25 import colander
26 from celery.task import task
27 from mako.template import Template
28
29 from rhodecode import events
30 from rhodecode.translation import lazy_ugettext
31 from rhodecode.integrations.types.base import IntegrationTypeBase
32 from rhodecode.integrations.schema import IntegrationSettingsSchemaBase
33
34 log = logging.getLogger()
35
36
37 class WebhookSettingsSchema(IntegrationSettingsSchemaBase):
38 url = colander.SchemaNode(
39 colander.String(),
40 title=lazy_ugettext('Webhook URL'),
41 description=lazy_ugettext('URL of the webhook to receive POST event.'),
42 default='',
43 validator=colander.url,
44 placeholder='https://www.example.com/webhook',
45 widget='string'
46 )
47 secret_token = colander.SchemaNode(
48 colander.String(),
49 title=lazy_ugettext('Secret Token'),
50 description=lazy_ugettext('String used to validate received payloads.'),
51 default='',
52 placeholder='secret_token',
53 widget='string'
54 )
55
56
57 class WebhookIntegrationType(IntegrationTypeBase):
58 key = 'webhook'
59 display_name = lazy_ugettext('Webhook')
60 valid_events = [
61 events.PullRequestCloseEvent,
62 events.PullRequestMergeEvent,
63 events.PullRequestUpdateEvent,
64 events.PullRequestCommentEvent,
65 events.PullRequestReviewEvent,
66 events.PullRequestCreateEvent,
67 events.RepoPushEvent,
68 events.RepoCreateEvent,
69 ]
70
71 @classmethod
72 def settings_schema(cls):
73 schema = WebhookSettingsSchema()
74 schema.add(colander.SchemaNode(
75 colander.Set(),
76 widget='checkbox_list',
77 choices=sorted([e.name for e in cls.valid_events]),
78 description="Events activated for this integration",
79 name='events'
80 ))
81 return schema
82
83 def send_event(self, event):
84 log.debug('handling event %s with webhook integration %s',
85 event.name, self)
86
87 if event.__class__ not in self.valid_events:
88 log.debug('event not valid: %r' % event)
89 return
90
91 if event.name not in self.settings['events']:
92 log.debug('event ignored: %r' % event)
93 return
94
95 data = event.as_dict()
96 post_to_webhook(data, self.settings)
97
98
99 @task(ignore_result=True)
100 def post_to_webhook(data, settings):
101 log.debug('sending event:%s to webhook %s', data['name'], settings['url'])
102 resp = requests.post(settings['url'], json={
103 'token': settings['secret_token'],
104 'event': data
105 })
106 resp.raise_for_status() # raise exception on a failed request
@@ -20,7 +20,7 b''
20
20
21 import logging
21 import logging
22 from rhodecode.integrations.registry import IntegrationTypeRegistry
22 from rhodecode.integrations.registry import IntegrationTypeRegistry
23 from rhodecode.integrations.types import slack
23 from rhodecode.integrations.types import webhook, slack
24
24
25 log = logging.getLogger(__name__)
25 log = logging.getLogger(__name__)
26
26
@@ -29,7 +29,12 b' log = logging.getLogger(__name__)'
29 # VCS's not having a pyramid context - move it to pyramid app configuration
29 # VCS's not having a pyramid context - move it to pyramid app configuration
30 # includeme level later to allow per instance integration setup
30 # includeme level later to allow per instance integration setup
31 integration_type_registry = IntegrationTypeRegistry()
31 integration_type_registry = IntegrationTypeRegistry()
32 integration_type_registry.register_integration_type(slack.SlackIntegrationType)
32
33 integration_type_registry.register_integration_type(
34 webhook.WebhookIntegrationType)
35 integration_type_registry.register_integration_type(
36 slack.SlackIntegrationType)
37
33
38
34 def integrations_event_handler(event):
39 def integrations_event_handler(event):
35 """
40 """
General Comments 0
You need to be logged in to leave comments. Login now