Annotate zerver.views.webhooks.freshdesk

Change the comments into docstrings.
Modified the return type of parse_freshdesk_event to always return a
list of str.
This commit is contained in:
Daw-Ran Liou 2016-06-05 14:03:26 -07:00 committed by Tim Abbott
parent c457f551ea
commit 7f0709b65c
1 changed files with 38 additions and 17 deletions

View File

@ -1,9 +1,10 @@
# Webhooks for external integrations.
"""Webhooks for external integrations."""
from __future__ import absolute_import
from django.http import HttpRequest, HttpResponse
from django.utils.translation import ugettext as _
from zerver.models import get_client
from zerver.models import get_client, UserProfile
from zerver.lib.actions import check_send_message
from zerver.lib.response import json_success, json_error
from zerver.lib.notifications import convert_html_to_markdown
@ -12,24 +13,32 @@ from zerver.decorator import REQ, has_request_variables, authenticated_rest_api_
import logging
import ujson
from six import text_type
from typing import Any, Dict, Optional, Tuple, Union
class TicketDict(dict):
"""
A helper class to turn a dictionary with ticket information into
an object where each of the keys is an attribute for easy access.
"""
def __getattr__(self, field):
# type: (str) -> Any
if "_" in field:
return self.get(field)
else:
return self.get("ticket_" + field)
def property_name(property, index):
# The Freshdesk API is currently pretty broken: statuses are customizable
# but the API will only tell you the number associated with the status, not
# the name. While we engage the Freshdesk developers about exposing this
# information through the API, since only FlightCar uses this integration,
# hardcode their statuses.
# type: (str, int) -> str
"""The Freshdesk API is currently pretty broken: statuses are customizable
but the API will only tell you the number associated with the status, not
the name. While we engage the Freshdesk developers about exposing this
information through the API, since only FlightCar uses this integration,
hardcode their statuses.
"""
statuses = ["", "", "Open", "Pending", "Resolved", "Closed",
"Waiting on Customer", "Job Application", "Monthly"]
priorities = ["", "Low", "Medium", "High", "Urgent"]
@ -41,10 +50,13 @@ def property_name(property, index):
else:
raise ValueError("Unknown property")
def parse_freshdesk_event(event_string):
# These are always of the form "{ticket_action:created}" or
# "{status:{from:4,to:6}}". Note the lack of string quoting: this isn't
# valid JSON so we have to parse it ourselves.
# type: (str) -> List[str]
"""These are always of the form "{ticket_action:created}" or
"{status:{from:4,to:6}}". Note the lack of string quoting: this isn't
valid JSON so we have to parse it ourselves.
"""
data = event_string.replace("{", "").replace("}", "").replace(",", ":").split(":")
if len(data) == 2:
@ -55,11 +67,13 @@ def parse_freshdesk_event(event_string):
# This is a property change event, like {status:{from:4,to:6}}. Pull out
# the property, from, and to states.
property, _, from_state, _, to_state = data
return (property, property_name(property, int(from_state)),
property_name(property, int(to_state)))
return [property, property_name(property, int(from_state)),
property_name(property, int(to_state))]
def format_freshdesk_note_message(ticket, event_info):
# There are public (visible to customers) and private note types.
# type: (TicketDict, List[str]) -> str
"""There are public (visible to customers) and private note types."""
note_type = event_info[1]
content = "%s <%s> added a %s note to [ticket #%s](%s)." % (
ticket.requester_name, ticket.requester_email, note_type,
@ -67,10 +81,13 @@ def format_freshdesk_note_message(ticket, event_info):
return content
def format_freshdesk_property_change_message(ticket, event_info):
# Freshdesk will only tell us the first event to match our webhook
# configuration, so if we change multiple properties, we only get the before
# and after data for the first one.
# type: (TicketDict, List[str]) -> str
"""Freshdesk will only tell us the first event to match our webhook
configuration, so if we change multiple properties, we only get the before
and after data for the first one.
"""
content = "%s <%s> updated [ticket #%s](%s):\n\n" % (
ticket.requester_name, ticket.requester_email, ticket.id, ticket.url)
# Why not `"%s %s %s" % event_info`? Because the linter doesn't like it.
@ -79,8 +96,10 @@ def format_freshdesk_property_change_message(ticket, event_info):
return content
def format_freshdesk_ticket_creation_message(ticket):
# They send us the description as HTML.
# type: (TicketDict) -> str
"""They send us the description as HTML."""
cleaned_description = convert_html_to_markdown(ticket.description)
content = "%s <%s> created [ticket #%s](%s):\n\n" % (
ticket.requester_name, ticket.requester_email, ticket.id, ticket.url)
@ -93,10 +112,12 @@ def format_freshdesk_ticket_creation_message(ticket):
return content
@authenticated_rest_api_view
@has_request_variables
def api_freshdesk_webhook(request, user_profile, payload=REQ(argument_type='body'),
stream=REQ(default='freshdesk')):
# type: (HttpRequest, UserProfile, Dict[str, Any], text_type) -> HttpResponse
ticket_data = payload["freshdesk_webhook"]
required_keys = [