mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 14:03:30 +00:00 
			
		
		
		
	integrations: Add webhook code, API endpoint, and tests for HelloSign.
This commit is contained in:
		
							
								
								
									
										
											BIN
										
									
								
								static/images/integrations/logos/hellosign.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/images/integrations/logos/hellosign.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 22 KiB  | 
							
								
								
									
										49
									
								
								zerver/fixtures/hellosign/hellosign_signatures.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								zerver/fixtures/hellosign/hellosign_signatures.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
{
 | 
			
		||||
	"signature_request": {
 | 
			
		||||
		"signature_request_id": "2b388914e3ae3b738bd4e2ee2850c677e6dc53d2",
 | 
			
		||||
		"title": "NDA with Acme Co.",
 | 
			
		||||
		"subject": "The NDA we talked about",
 | 
			
		||||
		"message": "Please sign this NDA and then we can discuss more. Let me know if you have any questions.",
 | 
			
		||||
		"test_mode": true,
 | 
			
		||||
		"metadata": {
 | 
			
		||||
			"custom_id": "1234",
 | 
			
		||||
			"custom_text": "NDA #9"
 | 
			
		||||
		},
 | 
			
		||||
		"is_complete": false,
 | 
			
		||||
		"is_declined": false,
 | 
			
		||||
		"has_error": false,
 | 
			
		||||
		"custom_fields": [],
 | 
			
		||||
		"response_data": [],
 | 
			
		||||
		"signing_url": "https://www.hellosign.com/sign/2b388914e3ae3b738bd4e2ee2850c677e6dc53d2",
 | 
			
		||||
		"signing_redirect_url": null,
 | 
			
		||||
		"final_copy_uri": "/v3/signature_request/final_copy/2b388914e3ae3b738bd4e2ee2850c677e6dc53d2",
 | 
			
		||||
		"files_url": "https://api.hellosign.com/v3/signature_request/files/2b388914e3ae3b738bd4e2ee2850c677e6dc53d2",
 | 
			
		||||
		"details_url": "https://www.hellosign.com/home/manage?guid=2b388914e3ae3b738bd4e2ee2850c677e6dc53d2",
 | 
			
		||||
		"requester_email_address": "me@hellosign.com",
 | 
			
		||||
		"signatures": [{
 | 
			
		||||
			"signature_id": "78caf2a1d01cd39cea2bc1cbb340dac3",
 | 
			
		||||
			"signer_email_address": "jack@example.com",
 | 
			
		||||
			"signer_name": "Jack",
 | 
			
		||||
			"order": 0,
 | 
			
		||||
			"status_code": "awaiting_signature",
 | 
			
		||||
			"signed_at": null,
 | 
			
		||||
			"last_viewed_at": null,
 | 
			
		||||
			"last_reminded_at": null,
 | 
			
		||||
			"has_pin": false
 | 
			
		||||
		}, {
 | 
			
		||||
			"signature_id": "616629ed37f8588d28600be17ab5d6b7",
 | 
			
		||||
			"signer_email_address": "jill@example.com",
 | 
			
		||||
			"signer_name": "Jill",
 | 
			
		||||
			"order": 1,
 | 
			
		||||
			"status_code": "signed",
 | 
			
		||||
			"signed_at": null,
 | 
			
		||||
			"last_viewed_at": null,
 | 
			
		||||
			"last_reminded_at": null,
 | 
			
		||||
			"has_pin": false
 | 
			
		||||
		}],
 | 
			
		||||
		"cc_email_addresses": [
 | 
			
		||||
			"lawyer1@hellosign.com",
 | 
			
		||||
			"lawyer2@example.com"
 | 
			
		||||
		]
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -126,6 +126,7 @@ WEBHOOK_INTEGRATIONS = [
 | 
			
		||||
    ),
 | 
			
		||||
    WebhookIntegration('gitlab', display_name='GitLab'),
 | 
			
		||||
    WebhookIntegration('gosquared', display_name='GoSquared'),
 | 
			
		||||
    WebhookIntegration('hellosign', display_name='HelloSign'),
 | 
			
		||||
    WebhookIntegration('helloworld', display_name='Hello World'),
 | 
			
		||||
    WebhookIntegration('heroku', display_name='Heroku'),
 | 
			
		||||
    WebhookIntegration('ifttt', function='zerver.views.webhooks.ifttt.api_iftt_app_webhook', display_name='IFTTT'),
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								zerver/tests/webhooks/test_hellosign.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								zerver/tests/webhooks/test_hellosign.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
# -*- coding: utf-8 -*-
 | 
			
		||||
from typing import Text
 | 
			
		||||
from zerver.lib.test_classes import WebhookTestCase
 | 
			
		||||
 | 
			
		||||
class HelloSignHookTests(WebhookTestCase):
 | 
			
		||||
    STREAM_NAME = 'hellosign'
 | 
			
		||||
    URL_TEMPLATE = "/api/v1/external/hellosign?stream={stream}&api_key={api_key}"
 | 
			
		||||
    FIXTURE_DIR_NAME = 'hellosign'
 | 
			
		||||
 | 
			
		||||
    def test_signatures_message(self):
 | 
			
		||||
        # type: () -> None
 | 
			
		||||
        expected_subject = "NDA with Acme Co."
 | 
			
		||||
        expected_message = ("The NDA with Acme Co. is awaiting the signature of "
 | 
			
		||||
                            "Jack and was just signed by Jill.")
 | 
			
		||||
        self.send_and_test_stream_message('signatures', expected_subject, expected_message,
 | 
			
		||||
                                          content_type="application/x-www-form-urlencoded")
 | 
			
		||||
 | 
			
		||||
    def get_body(self, fixture_name):
 | 
			
		||||
        # type: (Text) -> Text
 | 
			
		||||
        return self.fixture_data("hellosign", fixture_name, file_type="json")
 | 
			
		||||
							
								
								
									
										63
									
								
								zerver/views/webhooks/hellosign.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								zerver/views/webhooks/hellosign.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
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 six.moves import range
 | 
			
		||||
from typing import Dict, Any, Optional, Tuple, Union
 | 
			
		||||
 | 
			
		||||
def format_body(signatories, model_payload):
 | 
			
		||||
    # type: (List[Dict[str, Any]], Dict[str, Any]) -> str
 | 
			
		||||
    def append_separator(i, len_sig):
 | 
			
		||||
        # type: (int, int) -> None
 | 
			
		||||
        if i + 1 == len(signatories):
 | 
			
		||||
            result.append('.')
 | 
			
		||||
        elif i + 2 == len(signatories):
 | 
			
		||||
            result.append(' and')
 | 
			
		||||
        elif i + 3 != len(signatories):
 | 
			
		||||
            result.append(',')
 | 
			
		||||
 | 
			
		||||
    result = ["The {}".format(model_payload['contract_title'])] # type: Any
 | 
			
		||||
    for i, signatory in enumerate(signatories):
 | 
			
		||||
        name = model_payload['name_{}'.format(i)]
 | 
			
		||||
        if signatory['status_code'] == 'awaiting_signature':
 | 
			
		||||
            result.append(" is awaiting the signature of {}".format(name))
 | 
			
		||||
        elif signatory['status_code'] in ['signed', 'declined']:
 | 
			
		||||
            status = model_payload['status_{}'.format(i)]
 | 
			
		||||
            result.append(" was just {} by {}".format(status, name))
 | 
			
		||||
 | 
			
		||||
        append_separator(i, len(signatories))
 | 
			
		||||
    result = ''.join(result)
 | 
			
		||||
    return result
 | 
			
		||||
 | 
			
		||||
def ready_payload(signatories, payload):
 | 
			
		||||
    # type: (List[Dict[str, Any]], Dict[str, Dict[str, Any]]) -> Dict[str, Any]
 | 
			
		||||
    model_payload = {'contract_title': payload['signature_request']['title']}
 | 
			
		||||
    for i, signatory in enumerate(signatories):
 | 
			
		||||
        model_payload['name_{}'.format(i)] = signatory['signer_name']
 | 
			
		||||
        model_payload['status_{}'.format(i)] = signatory['status_code']
 | 
			
		||||
    return model_payload
 | 
			
		||||
 | 
			
		||||
@api_key_only_webhook_view('HelloSign')
 | 
			
		||||
@has_request_variables
 | 
			
		||||
def api_hellosign_webhook(request, user_profile, client,
 | 
			
		||||
                          payload=REQ(argument_type='body'),
 | 
			
		||||
                          stream=REQ(default='hellosign'),
 | 
			
		||||
                          topic=REQ(default=None)):
 | 
			
		||||
    # type: (HttpRequest, UserProfile, Client, Dict[str, Dict[str, Any]], text_type, text_type) -> HttpResponse
 | 
			
		||||
    try:
 | 
			
		||||
        model_payload = ready_payload(payload['signature_request']['signatures'],
 | 
			
		||||
                                      payload)
 | 
			
		||||
    except KeyError as e:
 | 
			
		||||
        return json_error(_("Missing key {} in JSON").format(str(e)))
 | 
			
		||||
 | 
			
		||||
    body = format_body(payload['signature_request']['signatures'], model_payload)
 | 
			
		||||
    topic = model_payload['contract_title']
 | 
			
		||||
    check_send_message(user_profile, client, 'stream', [stream],
 | 
			
		||||
                       topic, body)
 | 
			
		||||
    return json_success()
 | 
			
		||||
		Reference in New Issue
	
	Block a user