From 032b5e9db9f19d1c746a5a8e7297f79aa35b39d8 Mon Sep 17 00:00:00 2001 From: Jackson Date: Sun, 25 Dec 2016 01:50:28 +1100 Subject: [PATCH] integrations: Add webhook code, API endpoint, and tests for Delighted. --- .../images/integrations/logos/delighted.png | Bin 0 -> 36064 bytes ..._survey_response_updated_non_promoter.json | 21 +++++++++ ...hted_survey_response_updated_promoter.json | 21 +++++++++ zerver/lib/integrations.py | 1 + zerver/tests/webhooks/test_delighted.py | 37 ++++++++++++++++ zerver/views/webhooks/delighted.py | 40 ++++++++++++++++++ 6 files changed, 120 insertions(+) create mode 100644 static/images/integrations/logos/delighted.png create mode 100644 zerver/fixtures/delighted/delighted_survey_response_updated_non_promoter.json create mode 100644 zerver/fixtures/delighted/delighted_survey_response_updated_promoter.json create mode 100644 zerver/tests/webhooks/test_delighted.py create mode 100644 zerver/views/webhooks/delighted.py diff --git a/static/images/integrations/logos/delighted.png b/static/images/integrations/logos/delighted.png new file mode 100644 index 0000000000000000000000000000000000000000..234362b185edc07959bc5473a0b40cca477c7f4f GIT binary patch literal 36064 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 literal 0 HcmV?d00001 diff --git a/zerver/fixtures/delighted/delighted_survey_response_updated_non_promoter.json b/zerver/fixtures/delighted/delighted_survey_response_updated_non_promoter.json new file mode 100644 index 0000000000..18c0241dc1 --- /dev/null +++ b/zerver/fixtures/delighted/delighted_survey_response_updated_non_promoter.json @@ -0,0 +1,21 @@ +{ + "event_type": "survey_response.updated", + "event_id": "b8d057c59327541d7ec2104c0a9a255ad1997fb00831b9c6bbf09561e6d5cbd0", + "event_data": { + "id": "5435", + "person": { + "id": "5975", + "email": "paul_gravis@example.com", + "name": "Paul Gravis", + "created_at": 1482589349 + }, + "score": 5, + "comment": "Your service is slow, but nearly flawless! Keep up the good work!", + "permalink": "https://delighted.com/r/5pFDpmlyC8GUc5oxU6USto5VonSKAqOa", + "created_at": 1482589409, + "updated_at": 1482590009, + "person_properties": null, + "notes": [], + "tags": [] + } +} diff --git a/zerver/fixtures/delighted/delighted_survey_response_updated_promoter.json b/zerver/fixtures/delighted/delighted_survey_response_updated_promoter.json new file mode 100644 index 0000000000..dccbb9ba8b --- /dev/null +++ b/zerver/fixtures/delighted/delighted_survey_response_updated_promoter.json @@ -0,0 +1,21 @@ +{ + "event_type": "survey_response.updated", + "event_id": "b8d057c59327541d7ec2104c0a9a255ad1997fb00831b9c6bbf09561e6d5cbd0", + "event_data": { + "id": "5435", + "person": { + "id": "5975", + "email": "charlie_gravis@example.com", + "name": "Charlie Gravis", + "created_at": 1482589349 + }, + "score": 9, + "comment": "Your service is fast and flawless!", + "permalink": "https://delighted.com/r/5pFDpmlyC8GUc5oxU6USto5VonSKAqOa", + "created_at": 1482589409, + "updated_at": 1482590009, + "person_properties": null, + "notes": [], + "tags": [] + } +} diff --git a/zerver/lib/integrations.py b/zerver/lib/integrations.py index 001ac8f604..5c5ef26596 100644 --- a/zerver/lib/integrations.py +++ b/zerver/lib/integrations.py @@ -109,6 +109,7 @@ WEBHOOK_INTEGRATIONS = [ WebhookIntegration('circleci', display_name='CircleCI'), WebhookIntegration('codeship'), WebhookIntegration('crashlytics'), + WebhookIntegration('delighted', display_name='Delighted'), WebhookIntegration('deskdotcom', logo='static/images/integrations/logos/deskcom.png', display_name='Desk.com'), WebhookIntegration('freshdesk'), GithubIntegration( diff --git a/zerver/tests/webhooks/test_delighted.py b/zerver/tests/webhooks/test_delighted.py new file mode 100644 index 0000000000..dce3242874 --- /dev/null +++ b/zerver/tests/webhooks/test_delighted.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +from typing import Text +from zerver.lib.test_classes import WebhookTestCase + +class DelightedHookTests(WebhookTestCase): + STREAM_NAME = 'delighted' + URL_TEMPLATE = "/api/v1/external/delighted?stream={stream}&api_key={api_key}" + FIXTURE_DIR_NAME = 'delighted' + + def test_feedback_message_promoter(self): + # type: () -> None + expected_subject = "Survey Response" + expected_message = ("Kudos! You have a new promoter.\n" + ">Score of 9/10 from charlie_gravis@example.com" + "\n>Your service is fast and flawless!") + + self.send_and_test_stream_message('survey_response_updated_promoter', + expected_subject, + expected_message, + content_type="application/x-www-form-urlencoded") + + def test_feedback_message_non_promoter(self): + # type: () -> None + expected_subject = "Survey Response" + expected_message = ("Great! You have new feedback.\n" + ">Score of 5/10 from paul_gravis@example.com" + "\n>Your service is slow, but nearly flawless! " + "Keep up the good work!") + + self.send_and_test_stream_message('survey_response_updated_non_promoter', + expected_subject, + expected_message, + content_type="application/x-www-form-urlencoded") + + def get_body(self, fixture_name): + # type: (Text) -> Text + return self.fixture_data("delighted", fixture_name, file_type="json") diff --git a/zerver/views/webhooks/delighted.py b/zerver/views/webhooks/delighted.py new file mode 100644 index 0000000000..167bfd4a25 --- /dev/null +++ b/zerver/views/webhooks/delighted.py @@ -0,0 +1,40 @@ +from __future__ import absolute_import +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.decorator import REQ, has_request_variables, api_key_only_webhook_view + +from zerver.models import Client, UserProfile + +from django.http import HttpRequest, HttpResponse +from six import text_type +from typing import Dict, Any, Optional + +def body_template(score): + # type: (int) -> str + if score >= 7: + return 'Kudos! You have a new promoter.\n>Score of {score}/10 from {email}\n>{comment}' + else: + return 'Great! You have new feedback.\n>Score of {score}/10 from {email}\n>{comment}' + +@api_key_only_webhook_view("Delighted") +@has_request_variables +def api_delighted_webhook(request, user_profile, client, + payload=REQ(argument_type='body'), + stream=REQ(default='delighted'), + topic=REQ(default='Survey Response')): + # type: (HttpRequest, UserProfile, Client, Dict[str, Dict[str, Any]], text_type, text_type) -> HttpResponse + try: + person = payload['event_data']['person'] + selected_payload = {'email': person['email']} + selected_payload['score'] = payload['event_data']['score'] + selected_payload['comment'] = payload['event_data']['comment'] + except KeyError as e: + return json_error(_("Missing key {} in JSON").format(str(e))) + + BODY_TEMPLATE = body_template(selected_payload['score']) + body = BODY_TEMPLATE.format(**selected_payload) + + check_send_message(user_profile, client, 'stream', [stream], + topic, body) + return json_success()