def get_type(request: HttpRequest, payload: Dict[str, Any]) -> str: if payload.get('push'): return 'push' elif payload.get('fork'): return 'fork' elif payload.get('comment') and payload.get('commit'): return 'commit_comment' elif payload.get('commit_status'): return 'change_commit_status' elif payload.get('issue'): if payload.get('changes'): return "issue_updated" if payload.get('comment'): return 'issue_commented' return "issue_created" elif payload.get('pullrequest'): pull_request_template = 'pull_request_{}' # Note that we only need the HTTP header to determine pullrequest events. # We rely on the payload itself to determine the other ones. event_key = validate_extract_webhook_http_header( request, "X_EVENT_KEY", "BitBucket") action = re.match('pullrequest:(?P<action>.*)$', event_key) if action: action_group = action.group('action') if action_group in PULL_REQUEST_SUPPORTED_ACTIONS: return pull_request_template.format(action_group) else: event_key = validate_extract_webhook_http_header( request, "X_EVENT_KEY", "BitBucket") if event_key == 'repo:updated': return event_key raise UnknownTriggerType( "We don't support {} event type".format(event_key))
def get_type(request: HttpRequest, payload: Dict[str, Any]) -> str: if payload.get('push'): return 'push' elif payload.get('fork'): return 'fork' elif payload.get('comment') and payload.get('commit'): return 'commit_comment' elif payload.get('commit_status'): return 'change_commit_status' elif payload.get('issue'): if payload.get('changes'): return "issue_updated" if payload.get('comment'): return 'issue_commented' return "issue_created" elif payload.get('pullrequest'): pull_request_template = 'pull_request_{}' # Note that we only need the HTTP header to determine pullrequest events. # We rely on the payload itself to determine the other ones. event_key = validate_extract_webhook_http_header(request, "X_EVENT_KEY", "BitBucket") action = re.match('pullrequest:(?P<action>.*)$', event_key) if action: action_group = action.group('action') if action_group in PULL_REQUEST_SUPPORTED_ACTIONS: return pull_request_template.format(action_group) else: event_key = validate_extract_webhook_http_header(request, "X_EVENT_KEY", "BitBucket") if event_key == 'repo:updated': return event_key raise UnknownTriggerType("We don't support {} event type".format(event_key))
def get_type(request: HttpRequest, payload: WildValue) -> str: if "push" in payload: return "push" elif "fork" in payload: return "fork" elif "comment" in payload and "commit" in payload: return "commit_comment" elif "commit_status" in payload: return "change_commit_status" elif "issue" in payload: if "changes" in payload: return "issue_updated" if "comment" in payload: return "issue_commented" return "issue_created" elif "pullrequest" in payload: pull_request_template = "pull_request_{}" # Note that we only need the HTTP header to determine pullrequest events. # We rely on the payload itself to determine the other ones. event_key = validate_extract_webhook_http_header( request, "X_EVENT_KEY", "BitBucket") assert event_key is not None action = re.match("pullrequest:(?P<action>.*)$", event_key) if action: action_group = action.group("action") if action_group in PULL_REQUEST_SUPPORTED_ACTIONS: return pull_request_template.format(action_group) else: event_key = validate_extract_webhook_http_header( request, "X_EVENT_KEY", "BitBucket") if event_key == "repo:updated": return event_key raise UnsupportedWebhookEventType(event_key)
def get_event(request: HttpRequest, payload: Dict[str, Any], branches: str) -> Optional[str]: event = validate_extract_webhook_http_header(request, 'X_GITHUB_EVENT', 'GitHub') if event == 'pull_request': action = payload['action'] if action in ('opened', 'synchronize', 'reopened', 'edited'): return 'opened_or_update_pull_request' if action in ('assigned', 'unassigned'): return 'assigned_or_unassigned_pull_request' if action == 'closed': return 'closed_pull_request' if action == 'review_requested': return '{}_{}'.format(event, action) # Unsupported pull_request events if action in ('labeled', 'unlabeled', 'review_request_removed'): return None if event == 'push': if is_commit_push_event(payload): if branches is not None: branch = get_branch_name_from_ref(payload['ref']) if branches.find(branch) == -1: return None return "push_commits" else: return "push_tags" elif event in list(EVENT_FUNCTION_MAPPER.keys()) or event == 'ping': return event elif event in IGNORED_EVENTS: return None raise UnexpectedWebhookEventType('GitHub', event)
def get_event(request: HttpRequest, payload: Dict[str, Any], branches: str) -> Optional[str]: event = validate_extract_webhook_http_header(request, 'X_GITHUB_EVENT', 'GitHub') if event == 'pull_request': action = payload['action'] if action in ('opened', 'synchronize', 'reopened', 'edited'): return 'opened_or_update_pull_request' if action in ('assigned', 'unassigned'): return 'assigned_or_unassigned_pull_request' if action == 'closed': return 'closed_pull_request' logging.warning(u'Event pull_request with {} action is unsupported'.format(action)) return None if event == 'push': if is_commit_push_event(payload): if branches is not None: branch = get_branch_name_from_ref(payload['ref']) if branches.find(branch) == -1: return None return "push_commits" else: return "push_tags" elif event in list(EVENT_FUNCTION_MAPPER.keys()) or event == 'ping': return event logging.warning(u'Event {} is unknown and cannot be handled'.format(event)) return None
def get_event(request: HttpRequest, payload: Dict[str, Any], branches: Text) -> Optional[str]: event = validate_extract_webhook_http_header(request, 'X_GITHUB_EVENT', 'GitHub') if event == 'pull_request': action = payload['action'] if action in ('opened', 'synchronize', 'reopened', 'edited'): return 'opened_or_update_pull_request' if action in ('assigned', 'unassigned'): return 'assigned_or_unassigned_pull_request' if action == 'closed': return 'closed_pull_request' logging.warning( u'Event pull_request with {} action is unsupported'.format(action)) return None if event == 'push': if is_commit_push_event(payload): if branches is not None: branch = get_branch_name_from_ref(payload['ref']) if branches.find(branch) == -1: return None return "push_commits" else: return "push_tags" elif event in list(EVENT_FUNCTION_MAPPER.keys()) or event == 'ping': return event logging.warning(u'Event {} is unknown and cannot be handled'.format(event)) return None
def api_zapier_webhook( request: HttpRequest, user_profile: UserProfile, payload: Dict[str, Any] = REQ(argument_type='body') ) -> HttpResponse: # A request with the ZapierZulipApp user agent is a request from # the official Zulip app for Zapier user_agent = validate_extract_webhook_http_header(request, 'USER_AGENT', 'Zapier', fatal=False) if user_agent == 'ZapierZulipApp': event_type = payload.get('type') if event_type == 'auth': return json_success() elif event_type == 'stream': check_send_webhook_message(request, user_profile, payload['topic'], payload['content']) return json_success() topic = payload.get('topic') content = payload.get('content') if topic is None: topic = payload.get('subject') # Backwards-compatibility if topic is None: return json_error(_("Topic can't be empty")) if content is None: return json_error(_("Content can't be empty")) check_send_webhook_message(request, user_profile, topic, content) return json_success()
def api_github_webhook( request: HttpRequest, user_profile: UserProfile, payload: Dict[str, Any]=REQ(argument_type='body'), branches: Optional[str]=REQ(default=None), user_specified_topic: Optional[str]=REQ("topic", default=None)) -> HttpResponse: """ GitHub sends the event as an HTTP header. We have our own Zulip-specific concept of an event that often maps directly to the X_GITHUB_EVENT header's event, but we sometimes refine it based on the payload. """ header_event = validate_extract_webhook_http_header(request, "X_GITHUB_EVENT", "GitHub") if header_event is None: raise UnsupportedWebhookEventType("no header provided") event = get_zulip_event_name(header_event, payload, branches) if event is None: # This is nothing to worry about--get_event() returns None # for events that are valid but not yet handled by us. # See IGNORED_EVENTS, for example. return json_success() subject = get_subject_based_on_type(payload, event) body_function = EVENT_FUNCTION_MAPPER[event] helper = Helper( payload=payload, include_title=user_specified_topic is not None, ) body = body_function(helper) check_send_webhook_message(request, user_profile, subject, body) return json_success()
def api_gogs_webhook(request: HttpRequest, user_profile: UserProfile, payload: Dict[str, Any]=REQ(argument_type='body'), branches: Optional[str]=REQ(default=None)) -> HttpResponse: repo = payload['repository']['name'] event = validate_extract_webhook_http_header(request, 'X_GOGS_EVENT', 'Gogs') if event == 'push': branch = payload['ref'].replace('refs/heads/', '') if branches is not None and branches.find(branch) == -1: return json_success() body = format_push_event(payload) topic = SUBJECT_WITH_BRANCH_TEMPLATE.format( repo=repo, branch=branch ) elif event == 'create': body = format_new_branch_event(payload) topic = SUBJECT_WITH_BRANCH_TEMPLATE.format( repo=repo, branch=payload['ref'] ) elif event == 'pull_request': body = format_pull_request_event(payload) topic = SUBJECT_WITH_PR_OR_ISSUE_INFO_TEMPLATE.format( repo=repo, type='PR', id=payload['pull_request']['id'], title=payload['pull_request']['title'] ) else: raise UnexpectedWebhookEventType('Gogs', event) check_send_webhook_message(request, user_profile, topic, body) return json_success()
def api_gogs_webhook( request: HttpRequest, user_profile: UserProfile, payload: Dict[str, Any] = REQ(argument_type='body'), branches: Optional[str] = REQ(default=None) ) -> HttpResponse: repo = payload['repository']['name'] event = validate_extract_webhook_http_header(request, 'X_GOGS_EVENT', 'Gogs') if event == 'push': branch = payload['ref'].replace('refs/heads/', '') if branches is not None and branches.find(branch) == -1: return json_success() body = format_push_event(payload) topic = SUBJECT_WITH_BRANCH_TEMPLATE.format(repo=repo, branch=branch) elif event == 'create': body = format_new_branch_event(payload) topic = SUBJECT_WITH_BRANCH_TEMPLATE.format(repo=repo, branch=payload['ref']) elif event == 'pull_request': body = format_pull_request_event(payload) topic = SUBJECT_WITH_PR_OR_ISSUE_INFO_TEMPLATE.format( repo=repo, type='PR', id=payload['pull_request']['id'], title=payload['pull_request']['title']) else: raise UnexpectedWebhookEventType('Gogs', event) check_send_webhook_message(request, user_profile, topic, body) return json_success()
def get_event(request: HttpRequest, payload: Dict[str, Any], branches: str) -> Optional[str]: event = validate_extract_webhook_http_header(request, 'X_GITHUB_EVENT', 'GitHub') if event == 'pull_request': action = payload['action'] if action in ('opened', 'synchronize', 'reopened', 'edited'): return 'opened_or_update_pull_request' if action in ('assigned', 'unassigned'): return 'assigned_or_unassigned_pull_request' if action == 'closed': return 'closed_pull_request' if action == 'review_requested': return '{}_{}'.format(event, action) # Unsupported pull_request events if action in ('labeled', 'unlabeled', 'review_request_removed'): return None if event == 'push': if is_commit_push_event(payload): if branches is not None: branch = get_branch_name_from_ref(payload['ref']) if branches.find(branch) == -1: return None return "push_commits" else: return "push_tags" elif event in list(EVENT_FUNCTION_MAPPER.keys()) or event == 'ping': return event raise UnexpectedWebhookEventType('GitHub', event)
def get_event(request: HttpRequest, payload: Dict[str, Any], branches: Optional[str]) -> Optional[str]: event = validate_extract_webhook_http_header(request, 'X_GITLAB_EVENT', 'GitLab') if event == "System Hook": # Convert the event name to a Gitlab event title event_name = payload.get('event_name', payload.get('object_kind')) event = event_name.split("__")[0].replace("_", " ").title() event = f"{event} Hook" if event in [ 'Confidential Issue Hook', 'Issue Hook', 'Merge Request Hook', 'Wiki Page Hook' ]: action = payload['object_attributes'].get('action', 'open') event = f"{event} {action}" elif event in ['Confidential Note Hook', 'Note Hook']: action = payload['object_attributes'].get('noteable_type') event = f"{event} {action}" elif event == 'Push Hook': if branches is not None: branch = get_branch_name(payload) if branches.find(branch) == -1: return None if event in list(EVENT_FUNCTION_MAPPER.keys()): return event raise UnexpectedWebhookEventType('GitLab', event)
def api_bitbucket3_webhook( request: HttpRequest, user_profile: UserProfile, payload: WildValue = REQ(argument_type="body", converter=to_wild_value), branches: Optional[str] = REQ(default=None), user_specified_topic: Optional[str] = REQ("topic", default=None), ) -> HttpResponse: eventkey: Optional[str] if "eventKey" in payload: eventkey = payload["eventKey"].tame(check_string) else: eventkey = validate_extract_webhook_http_header( request, "X-Event-Key", "BitBucket", fatal=True ) assert eventkey is not None handler = EVENT_HANDLER_MAP.get(eventkey) if handler is None: raise UnsupportedWebhookEventType(eventkey) data = handler(payload, branches=branches, include_title=user_specified_topic) for element in data: check_send_webhook_message( request, user_profile, element["subject"], element["body"], eventkey, unquote_url_parameters=True, ) return json_success(request)
def get_event(request: HttpRequest, payload: WildValue, branches: Optional[str]) -> Optional[str]: event = validate_extract_webhook_http_header(request, "X_GITLAB_EVENT", "GitLab") if event == "System Hook": # Convert the event name to a GitLab event title event_name = payload.get("event_name", payload["object_kind"]).tame(check_string) event = event_name.split("__")[0].replace("_", " ").title() event = f"{event} Hook" if event in [ "Confidential Issue Hook", "Issue Hook", "Merge Request Hook", "Wiki Page Hook" ]: action = payload["object_attributes"].get("action", "open").tame(check_string) event = f"{event} {action}" elif event in ["Confidential Note Hook", "Note Hook"]: action = payload["object_attributes"]["noteable_type"].tame( check_string) event = f"{event} {action}" elif event == "Push Hook": if branches is not None: branch = get_branch_name(payload) if branches.find(branch) == -1: return None if event in list(EVENT_FUNCTION_MAPPER.keys()): return event raise UnsupportedWebhookEventType(event)
def test_webhook_http_header_header_exists(self) -> None: webhook_bot = get_user('*****@*****.**', get_realm('zulip')) request = HostRequestMock() request.META['HTTP_X_CUSTOM_HEADER'] = 'custom_value' request.user = webhook_bot header_value = validate_extract_webhook_http_header(request, 'X_CUSTOM_HEADER', 'test_webhook') self.assertEqual(header_value, 'custom_value')
def test_webhook_http_header_header_exists(self) -> None: webhook_bot = get_user('*****@*****.**', get_realm('zulip')) request = HostRequestMock() request.META['HTTP_X_CUSTOM_HEADER'] = 'custom_value' request.user = webhook_bot header_value = validate_extract_webhook_http_header(request, 'X_CUSTOM_HEADER', 'test_webhook') self.assertEqual(header_value, 'custom_value')
def test_webhook_http_header_header_exists(self) -> None: webhook_bot = get_user("*****@*****.**", get_realm("zulip")) request = HostRequestMock() request.META["HTTP_X_CUSTOM_HEADER"] = "custom_value" request.user = webhook_bot header_value = validate_extract_webhook_http_header( request, "X-Custom-Header", "test_webhook") self.assertEqual(header_value, "custom_value")
def test_webhook_http_header_header_does_not_exist(self) -> None: webhook_bot = get_user('*****@*****.**', get_realm('zulip')) webhook_bot.last_reminder = None notification_bot = self.notification_bot() request = HostRequestMock() request.user = webhook_bot request.path = 'some/random/path' exception_msg = "Missing the HTTP event header 'X_CUSTOM_HEADER'" with self.assertRaisesRegex(MissingHTTPEventHeader, exception_msg): validate_extract_webhook_http_header(request, 'X_CUSTOM_HEADER', 'test_webhook') msg = self.get_last_message() expected_message = MISSING_EVENT_HEADER_MESSAGE.format( bot_name=webhook_bot.full_name, request_path=request.path, header_name='X_CUSTOM_HEADER', integration_name='test_webhook', support_email=FromAddress.SUPPORT).rstrip() self.assertEqual(msg.sender.email, notification_bot.email) self.assertEqual(msg.content, expected_message)
def test_webhook_http_header_header_does_not_exist(self) -> None: webhook_bot = get_user('*****@*****.**', get_realm('zulip')) webhook_bot.last_reminder = None notification_bot = self.notification_bot() request = HostRequestMock() request.user = webhook_bot request.path = 'some/random/path' exception_msg = "Missing the HTTP event header 'X_CUSTOM_HEADER'" with self.assertRaisesRegex(MissingHTTPEventHeader, exception_msg): validate_extract_webhook_http_header(request, 'X_CUSTOM_HEADER', 'test_webhook') msg = self.get_last_message() expected_message = MISSING_EVENT_HEADER_MESSAGE.format( bot_name=webhook_bot.full_name, request_path=request.path, header_name='X_CUSTOM_HEADER', integration_name='test_webhook', support_email=FromAddress.SUPPORT ).rstrip() self.assertEqual(msg.sender.email, notification_bot.email) self.assertEqual(msg.content, expected_message)
def gogs_webhook_main(integration_name: str, http_header_name: str, format_pull_request_event: Callable[..., Any], request: HttpRequest, user_profile: UserProfile, payload: Dict[str, Any], branches: Optional[str], user_specified_topic: Optional[str]) -> HttpResponse: repo = payload['repository']['name'] event = validate_extract_webhook_http_header(request, http_header_name, integration_name) if event == 'push': branch = payload['ref'].replace('refs/heads/', '') if branches is not None and branch not in branches.split(','): return json_success() body = format_push_event(payload) topic = TOPIC_WITH_BRANCH_TEMPLATE.format(repo=repo, branch=branch) elif event == 'create': body = format_new_branch_event(payload) topic = TOPIC_WITH_BRANCH_TEMPLATE.format(repo=repo, branch=payload['ref']) elif event == 'pull_request': body = format_pull_request_event(payload, include_title=user_specified_topic is not None) topic = TOPIC_WITH_PR_OR_ISSUE_INFO_TEMPLATE.format( repo=repo, type='PR', id=payload['pull_request']['id'], title=payload['pull_request']['title']) elif event == 'issues': body = format_issues_event(payload, include_title=user_specified_topic is not None) topic = TOPIC_WITH_PR_OR_ISSUE_INFO_TEMPLATE.format( repo=repo, type='Issue', id=payload['issue']['number'], title=payload['issue']['title']) elif event == 'issue_comment': body = format_issue_comment_event(payload, include_title=user_specified_topic is not None) topic = TOPIC_WITH_PR_OR_ISSUE_INFO_TEMPLATE.format( repo=repo, type='Issue', id=payload['issue']['number'], title=payload['issue']['title']) else: raise UnexpectedWebhookEventType('Gogs', event) check_send_webhook_message(request, user_profile, topic, body) return json_success()
def get_template(request: HttpRequest, payload: Dict[str, Any]) -> str: message_template = 'The build [{build_name}]({build_url}) on branch {branch_name} ' event = validate_extract_webhook_http_header(request, 'X_NETLIFY_EVENT', 'Netlify') if event == 'deploy_failed': return message_template + payload['error_message'] elif event == 'deploy_locked': return message_template + 'is now locked.' elif event == 'deploy_unlocked': return message_template + 'is now unlocked.' elif event in EVENTS: return message_template + 'is now {state}.'.format(state=payload['state']) else: raise UnexpectedWebhookEventType('Netlify', event)
def test_webhook_http_header_header_does_not_exist(self) -> None: realm = get_realm("zulip") webhook_bot = get_user("*****@*****.**", realm) webhook_bot.last_reminder = None notification_bot = self.notification_bot(realm) request = HostRequestMock() request.user = webhook_bot request.path = "some/random/path" exception_msg = "Missing the HTTP event header 'X-Custom-Header'" with self.assertRaisesRegex(MissingHTTPEventHeader, exception_msg): validate_extract_webhook_http_header(request, "X-Custom-Header", "test_webhook") msg = self.get_last_message() expected_message = MISSING_EVENT_HEADER_MESSAGE.format( bot_name=webhook_bot.full_name, request_path=request.path, header_name="X-Custom-Header", integration_name="test_webhook", support_email=FromAddress.SUPPORT, ).rstrip() self.assertEqual(msg.sender.id, notification_bot.id) self.assertEqual(msg.content, expected_message)
def get_template(request: HttpRequest, payload: Dict[str, Any]) -> str: message_template = u'The build [{build_name}]({build_url}) on branch {branch_name} ' event = validate_extract_webhook_http_header(request, 'X_NETLIFY_EVENT', 'Netlify') if event == 'deploy_failed': return message_template + payload['error_message'] elif event == 'deploy_locked': return message_template + 'is now locked.' elif event == 'deploy_unlocked': return message_template + 'is now unlocked.' elif event in EVENTS: return message_template + 'is now {state}.'.format(state=payload['state']) else: raise UnexpectedWebhookEventType('Netlify', event)
def api_reviewboard_webhook( request: HttpRequest, user_profile: UserProfile, payload: Dict[str, Iterable[Dict[str, Any]]]=REQ(argument_type='body') ) -> HttpResponse: event_type = validate_extract_webhook_http_header( request, 'X_REVIEWBOARD_EVENT', 'ReviewBoard') body_function = RB_MESSAGE_FUNCTIONS.get(event_type) if body_function is not None: body = body_function(payload) topic = get_review_request_repo_title(payload) check_send_webhook_message(request, user_profile, topic, body) else: raise UnexpectedWebhookEventType('ReviewBoard', event_type) return json_success()
def api_zapier_webhook( request: HttpRequest, user_profile: UserProfile, payload: Dict[str, Any] = REQ(argument_type='body') ) -> HttpResponse: # A request with the ZapierZulipApp user agent is a request from # the official Zulip app for Zapier user_agent = validate_extract_webhook_http_header(request, 'USER_AGENT', 'Zapier', fatal=False) if user_agent == 'ZapierZulipApp': event_type = payload.get('type') if event_type == 'auth': # The bot's details are used by Zapier to format a connection # label for users to be able to distinguish between different # Zulip bots and API keys in their UI return json_success({ 'bot_name': user_profile.full_name, 'bot_email': user_profile.email, 'bot_id': user_profile.id }) elif event_type == 'stream': check_send_webhook_message(request, user_profile, payload['topic'], payload['content']) elif event_type == 'private': check_send_private_message_from_emails(user_profile, request.client, payload['to'], payload['content']) return json_success() topic = payload.get('topic') content = payload.get('content') if topic is None: topic = payload.get('subject') # Backwards-compatibility if topic is None: return json_error(_("Topic can't be empty")) if content is None: return json_error(_("Content can't be empty")) check_send_webhook_message(request, user_profile, topic, content) return json_success()
def api_reviewboard_webhook( request: HttpRequest, user_profile: UserProfile, payload: Dict[str, Iterable[Dict[str, Any]]]=REQ(argument_type='body') ) -> HttpResponse: event_type = validate_extract_webhook_http_header( request, 'X_REVIEWBOARD_EVENT', 'ReviewBoard') assert event_type is not None body_function = RB_MESSAGE_FUNCTIONS.get(event_type) if body_function is not None: body = body_function(payload) topic = get_review_request_repo_title(payload) check_send_webhook_message(request, user_profile, topic, body) else: raise UnexpectedWebhookEventType('ReviewBoard', event_type) return json_success()
def get_template(request: HttpRequest, payload: Dict[str, Any]) -> str: message_template = "The build [{build_name}]({build_url}) on branch {branch_name} " event = validate_extract_webhook_http_header(request, "X_NETLIFY_EVENT", "Netlify") if event == "deploy_failed": return message_template + payload["error_message"] elif event == "deploy_locked": return message_template + "is now locked." elif event == "deploy_unlocked": return message_template + "is now unlocked." elif event in EVENTS: return message_template + "is now {state}.".format( state=payload["state"]) else: raise UnsupportedWebhookEventType(event)
def api_groove_webhook(request: HttpRequest, user_profile: UserProfile, payload: Dict[str, Any]=REQ(argument_type='body')) -> HttpResponse: event = validate_extract_webhook_http_header(request, 'X_GROOVE_EVENT', 'Groove') # We listen to several events that are used for notifications. # Other events are ignored. if event in EVENTS_FUNCTION_MAPPER: try: body = EVENTS_FUNCTION_MAPPER[event](payload) except KeyError as e: logging.error('Required key not found : ' + e.args[0]) return json_error(_('Missing required data')) if body is not None: topic = 'notifications' check_send_webhook_message(request, user_profile, topic, body) return json_success()
def api_groove_webhook( request: HttpRequest, user_profile: UserProfile, payload: Dict[str, Any] = REQ(argument_type='body') ) -> HttpResponse: event = validate_extract_webhook_http_header(request, 'X_GROOVE_EVENT', 'Groove') assert event is not None handler = get_event_handler(event) body = handler(payload) topic = 'notifications' if body is not None: check_send_webhook_message(request, user_profile, topic, body) return json_success()
def api_groove_webhook( request: HttpRequest, user_profile: UserProfile, payload: Dict[str, Any] = REQ(argument_type="body"), ) -> HttpResponse: event = validate_extract_webhook_http_header(request, "X_GROOVE_EVENT", "Groove") assert event is not None handler = EVENTS_FUNCTION_MAPPER.get(event) if handler is None: raise UnsupportedWebhookEventType(event) body = handler(payload) topic = "notifications" if body is not None: check_send_webhook_message(request, user_profile, topic, body, event) return json_success()
def get_event(request: HttpRequest, payload: Dict[str, Any], branches: Optional[str]) -> Optional[str]: event = validate_extract_webhook_http_header(request, 'X_GITLAB_EVENT', 'GitLab') if event in ['Confidential Issue Hook', 'Issue Hook', 'Merge Request Hook', 'Wiki Page Hook']: action = payload['object_attributes'].get('action') event = "{} {}".format(event, action) elif event in ['Confidential Note Hook', 'Note Hook']: action = payload['object_attributes'].get('noteable_type') event = "{} {}".format(event, action) elif event == 'Push Hook': if branches is not None: branch = get_branch_name(payload) if branches.find(branch) == -1: return None if event in list(EVENT_FUNCTION_MAPPER.keys()): return event raise UnexpectedWebhookEventType('GitLab', event)
def get_event(request: HttpRequest, payload: Dict[str, Any], branches: Optional[str]) -> Optional[str]: event = validate_extract_webhook_http_header(request, 'X_GITLAB_EVENT', 'GitLab') if event in ['Issue Hook', 'Merge Request Hook', 'Wiki Page Hook']: action = payload['object_attributes'].get('action') event = "{} {}".format(event, action) elif event == 'Note Hook': action = payload['object_attributes'].get('noteable_type') event = "{} {}".format(event, action) elif event == 'Push Hook': if branches is not None: branch = get_branch_name(payload) if branches.find(branch) == -1: return None if event in list(EVENT_FUNCTION_MAPPER.keys()): return event raise UnexpectedWebhookEventType('GitLab', event)
def api_zapier_webhook(request: HttpRequest, user_profile: UserProfile, payload: Dict[str, Any]=REQ(argument_type='body')) -> HttpResponse: # A request with the ZapierZulipApp user agent is a request from # the official Zulip app for Zapier user_agent = validate_extract_webhook_http_header( request, 'USER_AGENT', 'Zapier', fatal=False) if user_agent == 'ZapierZulipApp': event_type = payload.get('type') if event_type == 'auth': # The bot's details are used by Zapier to format a connection # label for users to be able to distinguish between different # Zulip bots and API keys in their UI return json_success({ 'bot_name': user_profile.full_name, 'bot_email': user_profile.email, 'bot_id': user_profile.id }) elif event_type == 'stream': check_send_webhook_message( request, user_profile, payload['topic'], payload['content'] ) elif event_type == 'private': check_send_private_message_from_emails( user_profile, request.client, payload['to'], payload['content'] ) return json_success() topic = payload.get('topic') content = payload.get('content') if topic is None: topic = payload.get('subject') # Backwards-compatibility if topic is None: return json_error(_("Topic can't be empty")) if content is None: return json_error(_("Content can't be empty")) check_send_webhook_message(request, user_profile, topic, content) return json_success()
def api_reviewboard_webhook( request: HttpRequest, user_profile: UserProfile, payload: Dict[str, Sequence[Dict[str, Any]]] = REQ(argument_type="body"), ) -> HttpResponse: event_type = validate_extract_webhook_http_header(request, "X-ReviewBoard-Event", "Review Board") assert event_type is not None body_function = RB_MESSAGE_FUNCTIONS.get(event_type) if body_function is not None: body = body_function(payload) topic = get_review_request_repo_title(payload) check_send_webhook_message(request, user_profile, topic, body, event_type) else: raise UnsupportedWebhookEventType(event_type) return json_success(request)
def api_groove_webhook( request: HttpRequest, user_profile: UserProfile, payload: Dict[str, Any] = REQ(argument_type='body') ) -> HttpResponse: event = validate_extract_webhook_http_header(request, 'X_GROOVE_EVENT', 'Groove') # We listen to several events that are used for notifications. # Other events are ignored. if event in EVENTS_FUNCTION_MAPPER: try: body = EVENTS_FUNCTION_MAPPER[event](payload) except KeyError as e: logging.error('Required key not found : ' + e.args[0]) return json_error(_('Missing required data')) if body is not None: topic = 'notifications' check_send_webhook_message(request, user_profile, topic, body) return json_success()
def gogs_webhook_main( integration_name: str, http_header_name: str, format_pull_request_event: FormatPullRequestEvent, request: HttpRequest, user_profile: UserProfile, payload: Dict[str, Any], branches: Optional[str], user_specified_topic: Optional[str], ) -> HttpResponse: repo = payload["repository"]["name"] event = validate_extract_webhook_http_header(request, http_header_name, integration_name) if event == "push": branch = payload["ref"].replace("refs/heads/", "") if branches is not None and branch not in branches.split(","): return json_success() body = format_push_event(payload) topic = TOPIC_WITH_BRANCH_TEMPLATE.format( repo=repo, branch=branch, ) elif event == "create": body = format_new_branch_event(payload) topic = TOPIC_WITH_BRANCH_TEMPLATE.format( repo=repo, branch=payload["ref"], ) elif event == "pull_request": body = format_pull_request_event( payload, include_title=user_specified_topic is not None, ) topic = TOPIC_WITH_PR_OR_ISSUE_INFO_TEMPLATE.format( repo=repo, type="PR", id=payload["pull_request"]["id"], title=payload["pull_request"]["title"], ) elif event == "issues": body = format_issues_event( payload, include_title=user_specified_topic is not None, ) topic = TOPIC_WITH_PR_OR_ISSUE_INFO_TEMPLATE.format( repo=repo, type="issue", id=payload["issue"]["number"], title=payload["issue"]["title"], ) elif event == "issue_comment": body = format_issue_comment_event( payload, include_title=user_specified_topic is not None, ) topic = TOPIC_WITH_PR_OR_ISSUE_INFO_TEMPLATE.format( repo=repo, type="issue", id=payload["issue"]["number"], title=payload["issue"]["title"], ) elif event == "release": body = format_release_event( payload, include_title=user_specified_topic is not None, ) topic = TOPIC_WITH_RELEASE_TEMPLATE.format( repo=repo, tag=payload["release"]["tag_name"], title=payload["release"]["name"], ) else: raise UnsupportedWebhookEventType(event) check_send_webhook_message(request, user_profile, topic, body, event) return json_success()