def send(): global ds_account_id, ds_signer1_email, ds_signer1_name, ds_cc1_email, ds_cc1_name msg = ds_recipe_lib.init(ds_user_email, ds_user_pw, ds_integration_id, ds_account_id) if (msg != None): return {'ok': False, 'msg': msg} # Ready... # Possible create some fake people ds_signer1_email = ds_recipe_lib.get_signer_email(ds_signer1_email) ds_signer1_name = ds_recipe_lib.get_signer_name(ds_signer1_name) ds_cc1_email = ds_recipe_lib.get_signer_email(ds_cc1_email) ds_cc1_name = ds_recipe_lib.get_signer_name(ds_cc1_name) # STEP 1 - Login r = ds_recipe_lib.login() if (not r["ok"]): return r ds_account_id = ds_recipe_lib.ds_account_id # # STEP 2 - Create and send envelope with eventNotification # webhook_url = ds_recipe_lib.get_base_url() + webhook_path webhook_url = webhook_url.replace("http", "https") event_notification = { "url": webhook_url, "loggingEnabled": "true", # The api wants strings for true/false "requireAcknowledgment": "true", "useSoapInterface": "false", "includeCertificateWithSoap": "false", "signMessageWithX509Cert": "false", "includeDocuments": "true", "includeEnvelopeVoidReason": "true", "includeTimeZone": "true", "includeSenderAccountAsCustomField": "true", "includeDocumentFields": "true", "includeCertificateOfCompletion": "true", "envelopeEvents": [ # for this recipe, we're requesting notifications # for all envelope and recipient events { "envelopeEventStatusCode": "sent" }, { "envelopeEventStatusCode": "delivered" }, { "envelopeEventStatusCode": "completed" }, { "envelopeEventStatusCode": "declined" }, { "envelopeEventStatusCode": "voided" } ], "recipientEvents": [{ "recipientEventStatusCode": "Sent" }, { "recipientEventStatusCode": "Delivered" }, { "recipientEventStatusCode": "Completed" }, { "recipientEventStatusCode": "Declined" }, { "recipientEventStatusCode": "AuthenticationFailed" }, { "recipientEventStatusCode": "AutoResponded" }] } # construct the body of the request file_contents = open(doc_document_path, "rb").read() # Our goal: provide an email subject that is most meaningful to the recipients # The regex strips the 3 or 4 character extension from the filename. subject = "Please sign the " + re.sub('/\\.[^.\\s]{3,4}$/', '', doc_document_name) + " document" # File contents provided here instead of a multi-part request docs = [{ "documentId": "1", "name": doc_document_name, "documentBase64": base64.b64encode(file_contents) }] signers = [{ "email": ds_signer1_email, "name": ds_signer1_name, "recipientId": "1", "routingOrder": "1", "tabs": nda_fields() }] ccs = [{ "email": ds_cc1_email, "name": ds_cc1_name, "recipientId": "2", "routingOrder": "2" }] data = { "emailSubject": subject, "documents": docs, "recipients": { "signers": signers, "carbonCopies": ccs }, "eventNotification": event_notification, "status": "sent" } # append "/envelopes" to the baseUrl and use in the request url = ds_recipe_lib.ds_base_url + "/envelopes" try: r = requests.post(url, headers=ds_recipe_lib.ds_headers, json=data) except requests.exceptions.RequestException as e: return { 'ok': False, 'msg': "Error calling Envelopes:create: " + str(e) } status = r.status_code if (status != 201): return ({ 'ok': False, 'msg': "Error calling DocuSign Envelopes:create, status is: " + str(status) }) data = r.json() envelope_id = data['envelopeId'] setup_output_dir(envelope_id) # Instructions for reading the email html = "<h2>Signature request sent!</h2>" + \ "<p>Envelope ID: " + envelope_id + "</p>" + \ "<p>Signer: " + ds_signer1_name + "</p>" + \ "<p>CC: " + ds_cc1_name + "</p>" + \ "<h2>Next steps</h2>" + \ "<h3>1. View the incoming notifications and documents</h3>" + \ "<p><a href='" + ds_recipe_lib.get_base_url() + "/files/" + envelope_id_to_dir(envelope_id) + "'" + \ " class='btn btn-primary' role='button' target='_blank' style='margin-right:1.5em;'>" + \ "View Notification Files</a> (A new tab/window will be used.)</p>" + \ "<h3>2. Respond to the Signature Request</h3>" ds_signer1_email_access = ds_recipe_lib.get_temp_email_access( ds_signer1_email) if (ds_signer1_email_access): # A temp account was used for the email html += "<p>Respond to the request via your mobile phone by using the QR code: </p>" + \ "<p>" + ds_recipe_lib.get_temp_email_access_qrcode(ds_signer1_email_access) + "</p>" + \ "<p> or via <a target='_blank' href='" + ds_signer1_email_access + "'>your web browser.</a></p>" else: # A regular email account was used html += "<p>Respond to the request via your mobile phone or other mail tool.</p>" + \ "<p>The email was sent to " + ds_signer1_name + " <" + ds_signer1_email + "></p>" html += "<p>Webhook url: " + webhook_url + "</p>" return { "ok": True, "envelope_id": envelope_id, "ds_signer1_email": ds_signer1_email, "ds_signer1_name": ds_signer1_name, "ds_signer1_access": ds_signer1_email_access, "ds_signer1_qr": ds_signer1_email, "ds_cc1_email": ds_cc1_email, "ds_cc1_name": ds_cc1_name, "webhook_url": webhook_url, "html": html }
def list_all_unread(): request_json = request.json print request_json global ds_account_id msg = ds_recipe_lib.init(ds_user_email, ds_user_pw, ds_integration_id, ds_account_id) if (msg != None): return {'ok': False, 'msg': msg} r = ds_recipe_lib.login() if (not r["ok"]): return r else: print 'login successful' ds_account_id = ds_recipe_lib.ds_account_id action_conditions = request_json['queryResult']['action'] if action_conditions == 'email.ask': api_response = requests.get( "https://demo.docusign.net/restapi/v2/accounts/" + ds_account_id + "/search_folders/awaiting_my_signature?order=desc", headers=ds_recipe_lib.ds_headers) # print api_response.text response_text = json.loads(api_response.text) print response_text pending_envelops = response_text[u'folderItems'] pending_envelop_senders = [x["senderName"] for x in pending_envelops] fulfillmentText = "" for i, sender in enumerate(pending_envelop_senders): if i == 0: fulfillmentText += "You have one email from " + sender.split( )[0] + " " else: fulfillmentText += "one email from " + sender.split()[0] + " " response = {"fulfillmentText": fulfillmentText} elif action_conditions == 'email.from': #read document of a particular person person_name = request_json['queryResult']['parameters'][ 'name'] #some name to be inputted from Nitesh api_response = requests.get( "https://demo.docusign.net/restapi/v2/accounts/" + ds_account_id + "/search_folders/awaiting_my_signature?order=desc", headers=ds_recipe_lib.ds_headers) # print api_response.text response_text = json.loads(api_response.text) print response_text, 'ddddddddddddddddddddddddd' pending_envelops = response_text[u'folderItems'] pending_envelop_senders = [x["senderName"] for x in pending_envelops] envelop_ids = [x["envelopeId"] for x in pending_envelops] fulfillmentText = "" for i, sender in enumerate(pending_envelop_senders): if person_name in sender: new_api_response = json.loads( requests.get( "https://demo.docusign.net/restapi/v2/accounts/" + ds_account_id + "/envelopes/" + envelop_ids[i] + "/documents", headers=ds_recipe_lib.ds_headers).text) print new_api_response documents = new_api_response['envelopeDocuments'] final_documents = [] for d in documents: if d['documentId'] != 'certificate': final_documents.append(d) response = { "fulfillmentText": "There are " + str(len(final_documents)) + " documents to read" } break elif action_conditions == 'read.text': index_of_document = str( int(request_json['queryResult']['parameters']['number'])) person_name = request_json['queryResult']['parameters'][ 'name'] #some name to be inputted from Nitesh api_response = requests.get( "https://demo.docusign.net/restapi/v2/accounts/" + ds_account_id + "/search_folders/awaiting_my_signature?order=desc", headers=ds_recipe_lib.ds_headers) # print api_response.text response_text = json.loads(api_response.text) print response_text, 'ddddddddddddddddddddddddd' pending_envelops = response_text[u'folderItems'] pending_envelop_senders = [x["senderName"] for x in pending_envelops] envelop_ids = [x["envelopeId"] for x in pending_envelops] fulfillmentText = "" for i, sender in enumerate(pending_envelop_senders): if person_name in sender: new_api_response = json.loads( requests.get( "https://demo.docusign.net/restapi/v2/accounts/" + ds_account_id + "/envelopes/" + envelop_ids[i] + "/documents", headers=ds_recipe_lib.ds_headers).text) print new_api_response documents = new_api_response['envelopeDocuments'] doc_to_consider = [ x for x in documents if x['order'] == index_of_document ][0] pdf_file = requests.get( "https://demo.docusign.net/restapi/v2/accounts/" + ds_account_id + "/envelopes/" + envelop_ids[i] + "/documents/" + doc_to_consider['order'], headers=ds_recipe_lib.ds_headers) with open('pdf_file.pdf', 'wb') as f: f.write(pdf_file.content) pdfReaderObject = openFile("pdf_file.pdf") resumeText = entirePdfToText(pdfReaderObject) summary = summarize(resumeText, ratio=0.2, split=False) summary = summary.replace("\n", " ") response = {"fulfillmentText": summary} elif action_conditions == 'agreed': index_of_document = str( int(request_json['queryResult']['parameters']['number'])) person_name = request_json['queryResult']['parameters'][ 'name'] #some name to be inputted from Nitesh api_response = requests.get( "https://demo.docusign.net/restapi/v2/accounts/" + ds_account_id + "/search_folders/awaiting_my_signature?order=desc", headers=ds_recipe_lib.ds_headers) # print api_response.text response_text = json.loads(api_response.text) print response_text, 'ddddddddddddddddddddddddd' pending_envelops = response_text[u'folderItems'] pending_envelop_senders = [x["senderName"] for x in pending_envelops] envelop_ids = [x["envelopeId"] for x in pending_envelops] fulfillmentText = "" for i, sender in enumerate(pending_envelop_senders): if person_name in sender: new_api_response = json.loads( requests.get( "https://demo.docusign.net/restapi/v2/accounts/" + ds_account_id + "/envelopes/" + envelop_ids[i] + "/documents", headers=ds_recipe_lib.ds_headers).text) print new_api_response documents = new_api_response['envelopeDocuments'] doc_to_consider = [ x for x in documents if x['order'] == index_of_document ][0] envelope_created_resp = py_010_webhook_lib.create_envelope() print envelope_created_resp final_req_data = { "userName": envelope_created_resp["ds_signer1_name"], "email": envelope_created_resp["ds_signer1_email"], "recipientId": "1", "clientUserId": "1234", "authenticationMethod": "email", "returnUrl": "https://www.docusign.com/devcenter" } response = requests.post( "https://demo.docusign.net/restapi/v2/accounts/" + ds_account_id + "/envelopes/" + envelope_created_resp["envelope_id"] + "/views/recipient", headers=ds_recipe_lib.ds_headers, json=final_req_data).text print response, 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' response_url = json.loads(response)['url'] options = Options() options.add_argument("--headless") driver = webdriver.Firefox( firefox_options=options, executable_path=os.path.dirname(os.getcwd()) + "/geckodriver") driver.get(response_url) time.sleep(10) driver.find_element_by_id('action-bar-btn-continue').click() driver.find_element_by_class_name( 'signature-tab-content').click() driver.find_element_by_id('action-bar-btn-finish').click() driver.quit() response = {} else: response = {} print response, 'ssssssssssssssssssssssssssssssssssss' response = app.response_class(response=json.dumps(response), status=200, mimetype='application/json') return response
def send(): global ds_account_id, ds_signer1_email, ds_signer1_name, \ ds_cc1_email, ds_cc1_name msg = ds_recipe_lib.init(ds_user_email, ds_user_pw, ds_integration_id, ds_account_id) if msg != None: return {'ok': False, 'msg': msg} # Ready... # Possibly create some fake people # ds_signer1_email = ds_recipe_lib.get_signer_email(ds_signer1_email) # ds_signer1_name = ds_recipe_lib.get_signer_name(ds_signer1_name) # ds_cc1_email = ds_recipe_lib.get_signer_email(ds_cc1_email) # ds_cc1_name = ds_recipe_lib.get_signer_name(ds_cc1_name) ds_signer1_email = '*****@*****.**' ds_signer1_name = 'Signer 1' ds_signer2_email = '*****@*****.**' ds_signer2_name = 'Signer 2' ds_cc1_email = '*****@*****.**' ds_cc1_name = 'Carbon Copy' # STEP 1 - Login r = ds_recipe_lib.login() if not r['ok']: return r ds_account_id = ds_recipe_lib.ds_account_id # # STEP 2 - Create and send envelope # # construct the body of the request file_contents = open(doc_document_path, 'rb').read() file2_contents = open(doc2_document_path, 'rb').read() file3_contents = open(doc3_document_path, 'rb').read() # Please use the most accurate and relevant subject line. subject = 'Please sign the house documentation package' # File contents are provided here # The documents array can include multiple documents, of differing types. # All documents are converted to pdf prior to signing. # The fileExtension field defaults to "pdf". documents1 = [{ 'documentId': '1', 'name': doc_document_name, 'fileExtension': (os.path.splitext(doc_document_path)[1])[1:], 'documentBase64': base64.b64encode(file_contents), }, { 'documentId': '2', 'name': doc2_document_name, 'fileExtension': (os.path.splitext(doc2_document_path)[1])[1:], 'documentBase64': base64.b64encode(file2_contents), }] documents2 = [{ 'documentId': '1', 'name': doc_document_name, 'fileExtension': (os.path.splitext(doc_document_path)[1])[1:], 'documentBase64': base64.b64encode(file_contents), }, { 'documentId': '3', 'name': doc3_document_name, 'fileExtension': (os.path.splitext(doc3_document_path)[1])[1:], 'documentBase64': base64.b64encode(file3_contents), }] # The signing fields # # Invisible (white) Anchor field names for the NDA.pdf document: # * signer1sig # * signer1name # * signer1company # * signer1date # # Explicitly placed fields are used in the contractor_agreement # and on the house diagram # # Some anchor fields for document 3, the contractor_agreement.docx, use existing # content from the document: # * "Client Signature" # * "Client Name" # # NOTE: Anchor fields search ALL the documents in the envelope for # matches to the field's anchor text fields1 = { "signHereTabs": [ { "anchorString": "signer1sig", # Anchored for doc 1 "anchorXOffset": "0", "anchorYOffset": "0", "anchorUnits": "mms", "recipientId": "1", "name": "Please sign here", "optional": "false", "scaleValue": 1, "tabLabel": "signer1sig" }, { "documentId": "2", # Explicit position for doc 2 "pageNumber": "1", "recipientId": "2", "xPosition": "89", "yPosition": "40", "name": "Please sign here", "optional": "false", "scaleValue": 1, "tabLabel": "signer1_doc2" } ], "fullNameTabs": [{ "anchorString": "signer1name", # Anchored for doc 1 "anchorYOffset": "-6", "fontSize": "Size12", "recipientId": "1", "tabLabel": "Full Name", "name": "Full Name" }], "textTabs": [ { "anchorString": "signer1company", # Anchored for doc 1 "anchorYOffset": "-8", "fontSize": "Size12", "recipientId": "1", # Because the same tab label is "tabLabel": "Company", # used, these fields will have duplicate data "name": "Company", # Note that the account's "Data Population Scope" "required": "true" }, # must be set to "Envelope" to enable this feature. ], "dateSignedTabs": [ { "anchorString": "signer1date", # Anchored for doc 1 "anchorYOffset": "-6", "fontSize": "Size12", "recipientId": "1", "name": "Date Signed", "tabLabel": "date_signed" }, { "documentId": "2", # Explicit position for doc 2 "pageNumber": "1", "recipientId": "1", "xPosition": "89", "yPosition": "100", "fontSize": "Size12", "recipientId": "1", "name": "Date Signed", "tabLabel": "doc3_date_signed" } ] } fields2 = { "signHereTabs": [ { "anchorString": "signer1sig", # Anchored for doc 1 "anchorXOffset": "0", "anchorYOffset": "0", "anchorUnits": "mms", "recipientId": "1", "name": "Please sign here", "optional": "false", "scaleValue": 1, "tabLabel": "signer1sig" }, { "anchorString": "Client Signature", # Anchored for doc 3 "anchorXOffset": "0", "anchorYOffset": "-4", "anchorUnits": "mms", "recipientId": "1", "name": "Please sign here", "optional": "false", "scaleValue": 1, "tabLabel": "doc3_client_sig" } ], "fullNameTabs": [{ "anchorString": "signer1name", # Anchored for doc 1 "anchorYOffset": "-6", "fontSize": "Size12", "recipientId": "1", "tabLabel": "Full Name", "name": "Full Name" }], "textTabs": [ { "anchorString": "signer1company", # Anchored for doc 1 "anchorYOffset": "-8", "fontSize": "Size12", "recipientId": "1", # Because the same tab label is "tabLabel": "Company", # used, these fields will have duplicate data "name": "Company", # Note that the account's "Data Population Scope" "required": "true" }, # must be set to "Envelope" to enable this feature. { "anchorString": "Client Name", # Anchored for doc 3 "anchorYOffset": "-38", "fontSize": "Size12", "recipientId": "1", "tabLabel": "Company", "name": "Company", "required": "true" }, { "documentId": "3", # Explicit position for doc 3 "pageNumber": "1", "recipientId": "1", "xPosition": "145", "yPosition": "195", "fontSize": "Size10", "required": "true", "tabLabel": "Company", "name": "Company" } ], "dateSignedTabs": [{ "anchorString": "signer1date", # Anchored for doc 1 "anchorYOffset": "-6", "fontSize": "Size12", "recipientId": "1", "name": "Date Signed", "tabLabel": "date_signed" }] } signers1 = [{ 'email': ds_signer1_email, 'name': ds_signer1_name, 'recipientId': '1', 'routingOrder': '1', 'tabs': fields1, }] signers2 = [{ 'email': ds_signer2_email, 'name': ds_signer2_name, 'recipientId': '2', 'routingOrder': '2', 'tabs': fields2, }] ccs = [{ 'email': ds_cc1_email, 'name': ds_cc1_name, 'recipientId': '3', 'routingOrder': '3', }] data1 = { 'emailSubject': subject, 'documents': documents1, 'recipients': { 'signers': signers1, 'carbonCopies': ccs }, 'status': 'sent', } data2 = { 'emailSubject': subject, 'documents': documents2, 'recipients': { 'signers': signers2, 'carbonCopies': ccs }, 'status': 'sent', } # append "/envelopes" to the baseUrl and use in the request url = ds_recipe_lib.ds_base_url + '/envelopes' try: r = requests.post(url, headers=ds_recipe_lib.ds_headers, json=data1) except requests.exceptions.RequestException, e: return {'ok': False, 'msg': 'Error calling Envelopes:create: ' \ + str(e)}
def create_envelope(): global ds_account_id, ds_signer1_email, ds_signer1_name, ds_cc1_email, ds_cc1_name msg = ds_recipe_lib.init(ds_user_email, ds_user_pw, ds_integration_id, ds_account_id) if (msg != None): return {'ok': False, 'msg': msg} # Ready... # Possible create some fake people ds_signer1_email = "*****@*****.**" #ds_recipe_lib.get_signer_email(ds_signer1_email) ds_signer1_name = ds_recipe_lib.get_signer_name(ds_signer1_name) ds_cc1_email = ds_recipe_lib.get_signer_email(ds_cc1_email) ds_cc1_name = ds_recipe_lib.get_signer_name(ds_cc1_name) # STEP 1 - Login r = ds_recipe_lib.login() if (not r["ok"]): return r ds_account_id = ds_recipe_lib.ds_account_id # # STEP 2 - Create and send envelope with eventNotification # webhook_url = ds_recipe_lib.get_base_url() + webhook_path event_notification = {"url": webhook_url, "loggingEnabled": "true", # The api wants strings for true/false "requireAcknowledgment": "true", "useSoapInterface": "false", "includeCertificateWithSoap": "false", "signMessageWithX509Cert": "false", "includeDocuments": "true", "includeEnvelopeVoidReason": "true", "includeTimeZone": "true", "includeSenderAccountAsCustomField": "true", "includeDocumentFields": "true", "includeCertificateOfCompletion": "true", "envelopeEvents": [ # for this recipe, we're requesting notifications # for all envelope and recipient events {"envelopeEventStatusCode": "sent"}, {"envelopeEventStatusCode": "delivered"}, {"envelopeEventStatusCode": "completed"}, {"envelopeEventStatusCode": "declined"}, {"envelopeEventStatusCode": "voided"}], "recipientEvents": [ {"recipientEventStatusCode": "Sent"}, {"recipientEventStatusCode": "Delivered"}, {"recipientEventStatusCode": "Completed"}, {"recipientEventStatusCode": "Declined"}, {"recipientEventStatusCode": "AuthenticationFailed"}, {"recipientEventStatusCode": "AutoResponded"}] } # construct the body of the request file_contents = open(doc_document_path, "rb").read() # Our goal: provide an email subject that is most meaningful to the recipients # The regex strips the 3 or 4 character extension from the filename. subject = "Please sign the " + re.sub('/\\.[^.\\s]{3,4}$/', '', doc_document_name) + " document" # File contents provided here instead of a multi-part request docs = [{"documentId": "1", "name": doc_document_name, "documentBase64": base64.b64encode(file_contents)}] signers = [{"email": ds_signer1_email, "name": ds_signer1_name, "recipientId": "1", "clientUserId":"1234", "routingOrder": "1", "tabs": nda_fields()}] data = {"emailSubject": subject, "documents": docs, "recipients": {"signers": signers}, "eventNotification": event_notification, "status": "sent" } # append "/envelopes" to the baseUrl and use in the request url = ds_recipe_lib.ds_base_url + "/envelopes" try: r = requests.post(url, headers=ds_recipe_lib.ds_headers, json=data) except requests.exceptions.RequestException as e: return {'ok': False, 'msg': "Error calling Envelopes:create: " + str(e)} status = r.status_code if (status != 201): return ({'ok': False, 'msg': "Error calling DocuSign Envelopes:create, status is: " + str(status)}) data = r.json() envelope_id = data['envelopeId'] setup_output_dir(envelope_id) ds_signer1_email_access = ds_recipe_lib.get_temp_email_access(ds_signer1_email) return {"ok": True, "envelope_id": envelope_id, "ds_signer1_email": ds_signer1_email, "ds_signer1_name": ds_signer1_name, "ds_signer1_access": ds_signer1_email_access, "ds_signer1_qr": ds_signer1_email, "ds_cc1_email": ds_cc1_email, "ds_cc1_name": ds_cc1_name, "webhook_url": webhook_url }