lib/docusign_rest/client.rb in docusign_rest-0.3.1 vs lib/docusign_rest/client.rb in docusign_rest-0.3.2

- old
+ new

@@ -328,28 +328,46 @@ def get_signers(signers, options={}) doc_signers = [] signers.each_with_index do |signer, index| doc_signer = { - email: signer[:email], - name: signer[:name], accessCode: '', addAccessCodeToEmail: false, customFields: signer[:custom_fields], - iDCheckConfigurationName: nil, - iDCheckInformationInput: nil, + idCheckConfigurationName: signer[:id_check_configuration_name], + idCheckInformationInput: nil, inheritEmailNotificationConfiguration: false, - note: '', + note: signer[:note], phoneAuthentication: nil, recipientAttachment: nil, - recipientId: "#{index + 1}", - requireIdLookup: false, + requireIdLookup: signer[:require_id_lookup], roleName: signer[:role_name], routingOrder: signer[:routing_order] || index + 1, socialAuthentications: nil } + recipient_id = signer[:recipient_id] || index + 1 + doc_signer[:recipientId] = recipient_id + doc_signer[:clientUserId] = recipient_id if signer[:embedded_signing] + + if signer[:id_check_information_input] + doc_signer[:idCheckInformationInput] = + get_id_check_information_input(signer[:id_check_information_input]) + end + + if signer[:phone_authentication] + doc_signer[:phoneAuthentication] = + get_phone_authentication(signer[:phone_authentication]) + end + + if signer[:signing_group_id] + doc_signer[:signingGroupId] = signer[:signing_group_id] + else + doc_signer[:email] = signer[:email] + doc_signer[:name] = signer[:name] + end + if signer[:email_notification] doc_signer[:emailNotification] = signer[:email_notification] end if signer[:embedded] @@ -727,11 +745,17 @@ # statusDateTime - The date/time the envelope was created # uri - The relative envelope uri def create_envelope_from_document(options={}) ios = create_file_ios(options[:files]) file_params = create_file_params(ios) + recipients = if options[:certified_deliveries].nil? || options[:certified_deliveries].empty? + { signers: get_signers(options[:signers]) } + else + { certifiedDeliveries: get_signers(options[:certified_deliveries]) } + end + post_hash = { emailBlurb: "#{options[:email][:body] if options[:email]}", emailSubject: "#{options[:email][:subject] if options[:email]}", documents: get_documents(ios), recipients: { @@ -1157,10 +1181,31 @@ generate_log(request, response, uri) JSON.parse(response.body) end + # Public retrieves a png of a page of a document in an envelope + # + # envelope_id - ID of the envelope from which the doc will be retrieved + # document_id - ID of the document to retrieve + # page_number - page number to retrieve + # + # Returns the png as a bytestream + def get_page_image(options={}) + envelope_id = options[:envelope_id] + document_id = options[:document_id] + page_number = options[:page_number] + + uri = build_uri("/accounts/#{acct_id}/envelopes/#{envelope_id}/documents/#{document_id}/pages/#{page_number}/page_image") + + http = initialize_net_http_ssl(uri) + request = Net::HTTP::Get.new(uri.request_uri, headers) + response = http.request(request) + generate_log(request, response, uri) + response.body + end + # Public retrieves the attached file from a given envelope # # envelope_id - ID of the envelope from which the doc will be retrieved # document_id - ID of the document to retrieve # local_save_path - Local absolute path to save the doc to including the @@ -1516,11 +1561,11 @@ post_body = { "status" =>"voided", "voidedReason" => options[:voided_reason] || "No reason provided." }.to_json - uri = build_uri("/accounts/#{acct_id}/envelopes/#{options[:folder_id]}") + uri = build_uri("/accounts/#{acct_id}/envelopes/#{options[:envelope_id]}") http = initialize_net_http_ssl(uri) request = Net::HTTP::Put.new(uri.request_uri, headers(content_type)) request.body = post_body response = http.request(request) @@ -1654,21 +1699,208 @@ def add_recipient_tabs(options={}) content_type = {'Content-Type' => 'application/json'} content_type.merge(options[:headers]) if options[:headers] uri = build_uri("/accounts/#{@acct_id}/envelopes/#{options[:envelope_id]}/recipients/#{options[:recipient_id]}/tabs") - post_body = options[:tabs].to_json + tabs = options[:tabs] + index = options[:recipient_id] - 1 + post_body = { + approveTabs: nil, + checkboxTabs: nil, + companyTabs: nil, + dateSignedTabs: get_tabs(tabs[:date_signed_tabs], options, index), + dateTabs: nil, + declineTabs: nil, + emailTabs: nil, + envelopeIdTabs: nil, + fullNameTabs: nil, + listTabs: nil, + noteTabs: nil, + numberTabs: nil, + radioGroupTabs: nil, + initialHereTabs: get_tabs(tabs[:initial_here_tabs], options.merge!(initial_here_tab: true), index), + signHereTabs: get_tabs(tabs[:sign_here_tabs], options.merge!(sign_here_tab: true), index), + signerAttachmentTabs: nil, + ssnTabs: nil, + textTabs: nil, + titleTabs: nil, + zipTabs: nil + }.to_json + http = initialize_net_http_ssl(uri) request = Net::HTTP::Post.new(uri.request_uri, headers(content_type)) request.body = post_body response = http.request(request) generate_log(request, response, uri) JSON.parse(response.body) end + # Public method - Creates Signing group + # group_name: The display name for the signing group. This can be a maximum of 100 characters. + # users: An array of group members for the signing group. (see example below) + # It is composed of two elements: + # name – The name for the group member. This can be a maximum of 100 characters. + # email – The email address for the group member. This can be a maximum of 100 characters. + # [ + # {name: 'test1', email: 'test1@ygrene.us'} + # {name: 'test2', email: 'test2@ygrene.us'} + # ] + # + # + # The response returns a success or failure with any error messages. + # For successes DocuSign generates a signingGroupId for each group, which is included in the response. + # The response also includes information about when the group was created and modified, + # including the account user that created and modified the group. + def create_signing_group(options={}) + content_type = { 'Content-Type' => 'application/json' } + content_type.merge(options[:headers]) if options[:headers] + + group_users = [] + if options[:users] + options[:users].each do |user| + group_users << { + userName: user[:name], + email: user[:email] + } + end + end + + post_body = { + groups: [ + { + groupName: options[:group_name], + groupType: 'sharedSigningGroup', + users: group_users + } + ] + }.to_json + + uri = build_uri("/accounts/#{@acct_id}/signing_groups") + + http = initialize_net_http_ssl(uri) + + request = Net::HTTP::Post.new(uri.request_uri, headers(content_type)) + request.body = post_body + + response = http.request(request) + + JSON.parse(response.body) + end + + # Public method - deletes a signing group + # See https://docs.docusign.com/esign/restapi/SigningGroups/SigningGroups/delete/ + # + # signingGroupId - ID of the signing group to delete + # + # Returns the success or failure of each group being deleted. Failed operations on array elements will add the "errorDetails" + # structure containing an error code and message. If "errorDetails" is null, then + # the operation was successful for that item. + def delete_signing_groups(options={}) + content_type = {'Content-Type' => 'application/json'} + content_type.merge!(options[:headers]) if options[:headers] + + uri = build_uri("/accounts/#{@acct_id}/signing_groups") + + groups = options[:groups] + groups.each{|h| h[:signingGroupId] = h.delete(:signing_group_id) if h.key?(:signing_group_id)} + post_body = { + groups: groups + }.to_json + + http = initialize_net_http_ssl(uri) + request = Net::HTTP::Delete.new(uri.request_uri, headers(content_type)) + request.body = post_body + + response = http.request(request) + JSON.parse(response.body) + end + + # Public method - updates signing group users + # See https://docs.docusign.com/esign/restapi/SigningGroups/SigningGroupUsers/update/ + # + # signingGroupId - ID of the signing group to update + # + # Returns the success or failure of each user being updated. Failed operations on array elements will add the "errorDetails" + # structure containing an error code and message. If "errorDetails" is null, then + # the operation was successful for that item. + def update_signing_group_users(options={}) + content_type = {'Content-Type' => 'application/json'} + content_type.merge!(options[:headers]) if options[:headers] + + uri = build_uri("/accounts/#{@acct_id}/signing_groups/#{options[:signing_group_id]}/users") + + users = options[:users] + users.each do |user| + user[:userName] = user.delete(:user_name) if user.key?(:user_name) + end + post_body = { + users: users + }.to_json + + http = initialize_net_http_ssl(uri) + request = Net::HTTP::Put.new(uri.request_uri, headers(content_type)) + request.body = post_body + + response = http.request(request) + JSON.parse(response.body) + end + + # Public: Retrieves a list of available signing groups + def get_signing_groups + uri = build_uri("/accounts/#{@acct_id}/signing_groups") + + http = initialize_net_http_ssl(uri) + request = Net::HTTP::Get.new(uri.request_uri, headers({ 'Content-Type' => 'application/json' })) + JSON.parse(http.request(request).body) + end + + # Public: Update envelope recipients + def update_envelope_recipients(options={}) + content_type = {'Content-Type' => 'application/json'} + content_type.merge(options[:headers]) if options[:headers] + + resend = options[:resend].present? + uri = build_uri("/accounts/#{@acct_id}/envelopes/#{options[:envelope_id]}/recipients?resend_envelope=#{resend}") + + signers = options[:signers] + signers.each do |signer| + signer[:recipientId] = signer.delete(:recipient_id) if signer.key?(:recipient_id) + signer[:clientUserId] = signer.delete(:client_user_id) if signer.key?(:client_user_id) + end + post_body = { + signers: signers + }.to_json + + http = initialize_net_http_ssl(uri) + request = Net::HTTP::Put.new(uri.request_uri, headers(content_type)) + request.body = post_body + + response = http.request(request) + JSON.parse(response.body) + end + + # Public: Add recipients to envelope + def add_envelope_recipients(options={}) + content_type = {'Content-Type' => 'application/json'} + content_type.merge(options[:headers]) if options[:headers] + + uri = build_uri("/accounts/#{@acct_id}/envelopes/#{options[:envelope_id]}/recipients?resend_envelope=true") + + post_body = { + signers: get_signers(options[:signers]) + }.to_json + + http = initialize_net_http_ssl(uri) + request = Net::HTTP::Post.new(uri.request_uri, headers(content_type)) + request.body = post_body + + response = http.request(request) + JSON.parse(response.body) + end + private # Private: Generates a standardized log of the request and response pair # to and from DocuSign for logging and API Certification. # and resulting list is set to the publicly accessible: @previous_call_log @@ -1687,8 +1919,60 @@ log << '--DocuSign RESPONSE--' log << "HTTP/#{response.http_version} #{response.code} #{response.msg}" response.each_capitalized{ |k,v| log << "#{k}: #{v}" } log << "Body: #{response.body}" @previous_call_log = log + end + + def get_id_check_information_input(input) + { + addressInformationInput: get_address_information_input( + input.dig(:address_information_input, :address_information)), + ssn4InformationInput: get_ssn4_information_input(input[:ssn4_information_input]), + dobInformationInput: get_dob_information_input(input[:dob_information_input]) + } + end + + def get_address_information_input(input) + return {} unless input + { + addressInformation:{ + street1: input[:street1], + city: input[:city], + state: input[:state], + zip: input[:zip], + zipPlus4: input[:zip_plus4], + }, + displayLevelCode: 'DoNotDisplay', + receiveInResponse: true, + } + end + + def get_phone_authentication(input) + return {} unless input + { + recipMayProvideNumber: true, + validateRecipProvidedNumber: true, + recordVoicePrint: true, + senderProvidedNumbers: input[:sender_provided_numbers], + } + end + + def get_ssn4_information_input(input) + return {} unless input + { + ssn4: input[:ssn4], + displayLevelCode: 'DoNotDisplay', + receiveInResponse: true, + } + end + + def get_dob_information_input(input) + return {} unless input + { + dateOfBirth: input[:date_of_birth], + displayLevelCode: 'DoNotDisplay', + receiveInResponse: true, + } end end end