Skip to content

Commit

Permalink
Merge pull request #147 from docusign/feature/webforms-example
Browse files Browse the repository at this point in the history
Web Forms code example
  • Loading branch information
paigesrossi authored Feb 15, 2024
2 parents 0936c5e + b4760dc commit 6897222
Show file tree
Hide file tree
Showing 16 changed files with 353 additions and 8 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ gem 'docusign_click', '~> 1.4.0'
gem 'docusign_esign', '~> 3.25.0'
gem 'docusign_monitor', '~> 1.2.0'
gem 'docusign_rooms', '~> 1.3.0'
gem 'docusign_webforms', '~> 1.0.0'
gem 'omniauth-oauth2', '~> 1.8.0'
gem 'omniauth-rails_csrf_protection'

Expand Down
17 changes: 9 additions & 8 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ GEM
json (~> 2.1, >= 2.1.0)
jwt (~> 2.2, >= 2.2.1)
typhoeus (~> 1.0, >= 1.0.1)
docusign_webforms (1.0.0)
addressable (~> 2.7, >= 2.7.0)
json (~> 2.1, >= 2.1.0)
jwt (~> 2.2, >= 2.2.1)
typhoeus (~> 1.0, >= 1.0.1)
erubi (1.12.0)
ethon (0.16.0)
ffi (>= 1.15.0)
Expand All @@ -133,7 +138,6 @@ GEM
ruby2_keywords (>= 0.0.4)
faraday-net_http (3.0.2)
ffi (1.15.5)
ffi (1.15.5-x64-mingw-ucrt)
globalid (1.1.0)
activesupport (>= 5.0)
hashie (5.0.0)
Expand Down Expand Up @@ -173,9 +177,7 @@ GEM
net-smtp (0.3.3)
net-protocol
nio4r (2.5.9)
nokogiri (1.15.4-x64-mingw-ucrt)
racc (~> 1.4)
nokogiri (1.15.4-x86_64-linux)
nokogiri (1.15.4-x86_64-darwin)
racc (~> 1.4)
oauth2 (2.0.9)
faraday (>= 0.17.3, < 3.0)
Expand Down Expand Up @@ -293,8 +295,7 @@ GEM
actionpack (>= 5.2)
activesupport (>= 5.2)
sprockets (>= 3.0.0)
sqlite3 (1.6.4-x64-mingw-ucrt)
sqlite3 (1.6.4-x86_64-linux)
sqlite3 (1.6.4-x86_64-darwin)
test-unit (3.6.1)
power_assert
thor (1.2.2)
Expand Down Expand Up @@ -327,8 +328,7 @@ GEM
zeitwerk (2.6.11)

PLATFORMS
x64-mingw-ucrt
x86_64-linux
x86_64-darwin-21

DEPENDENCIES
bootsnap (~> 1.7.3)
Expand All @@ -341,6 +341,7 @@ DEPENDENCIES
docusign_esign (~> 3.25.0)
docusign_monitor (~> 1.2.0)
docusign_rooms (~> 1.3.0)
docusign_webforms (~> 1.0.0)
jbuilder (~> 2.11.5)
listen (~> 3.8.0)
matrix (~> 0.4.2)
Expand Down
3 changes: 3 additions & 0 deletions app/assets/javascripts/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const DS_SEARCH = (function () {
ROOMS: "rooms",
ADMIN: "admin",
CONNECT: "connect",
WEBFORMS: "webforms",
}

const processJSONData = function () {
Expand Down Expand Up @@ -142,6 +143,8 @@ const DS_SEARCH = (function () {
return "eg";
case API_TYPES.CONNECT:
return "cneg";
case API_TYPES.WEBFORMS:
return "weg";
}
}

Expand Down
56 changes: 56 additions & 0 deletions app/controllers/webforms/weg001_create_instance_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# frozen_string_literal: true

class Webforms::Weg001CreateInstanceController < EgController
before_action -> { check_auth('WebForms') }
before_action -> { @example = Utils::ManifestUtils.new.get_example(@manifest, 1, 'WebForms') }

def create_web_form_template
args = {
template_name: 'Web Form Example Template',
account_id: session[:ds_account_id],
base_path: session[:ds_base_path],
access_token: session[:ds_access_token]
}

web_form_template_id = Webforms::Eg001CreateInstanceService.new(args).create_web_form_template
Utils::FileUtils.new.replace_template_id(File.join('data', Rails.application.config.web_form_config_file), web_form_template_id)
session[:web_form_template_id] = web_form_template_id

redirect_to '/weg001webForm'
end

def create_web_form_instance
args = {
form_name: 'Web Form Example Template',
client_user_id: '1234-5678-abcd-ijkl',
account_id: session[:ds_account_id],
base_path: Rails.application.config.webforms_host,
access_token: session[:ds_access_token]
}
create_instance_service = Webforms::Eg001CreateInstanceService.new(args)
web_forms = create_instance_service.list_web_forms
results = create_instance_service.create_web_form_instance web_forms.items.first.id

@integration_key = Rails.application.config.integration_key
@form_url = results.form_url
@instance_token = results.instance_token
render 'webforms/weg001_create_instance/web_form_embed'
end

def get
additional_page = @example['AdditionalPage'].find { |p| p['Name'] == 'create_web_form_template' }
@example['ExampleDescription'] = additional_page['ResultsPageText']

render 'webforms/weg001_create_instance/get'
end

def get_web_form_create_view
redirect_to '/weg001' if session[:web_form_template_id].nil?

additional_page = @example['AdditionalPage'].find { |p| p['Name'] == 'create_web_form' }
@title = @example['ExampleName']
@description = additional_page['ResultsPageText']

render 'webforms/weg001_create_instance/web_form_create'
end
end
5 changes: 5 additions & 0 deletions app/services/jwt_auth/jwt_creator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def self.consent_url(state, api)
scope = 'signature impersonation dtr.rooms.read dtr.rooms.write dtr.documents.read dtr.documents.write dtr.profile.read dtr.profile.write dtr.company.read dtr.company.write room_forms' if api == 'Rooms'
scope = 'signature impersonation click.manage click.send' if api == 'Click'
scope = 'signature impersonation organization_read group_read permission_read user_read user_write account_read domain_read identity_provider_read user_data_redact asset_group_account_read asset_group_account_clone_write asset_group_account_clone_read' if api == 'Admin'
scope = 'signature webforms_read webforms_instance_read webforms_instance_write' if api == 'WebForms'

base_uri = "#{Rails.configuration.authorization_server}/oauth/auth"
response_type = 'code'
Expand Down Expand Up @@ -45,6 +46,10 @@ def initialize(session)
scope = 'signature organization_read group_read permission_read user_read user_write account_read domain_read identity_provider_read user_data_redact asset_group_account_read asset_group_account_clone_write asset_group_account_clone_read'
@client_module = DocuSign_Admin
end
if session[:api] == 'WebForms'
scope = 'signature webforms_read webforms_instance_read webforms_instance_write'
@client_module = DocuSign_WebForms
end

@scope = scope
@api_client = create_initial_api_client(host: Rails.configuration.aud, client_module: @client_module, debugging: false)
Expand Down
10 changes: 10 additions & 0 deletions app/services/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,14 @@ def get_user_id(args)
user_info.sub
end
end

class FileUtils
def replace_template_id(file_path, template_id)
content = File.read(file_path)

content.gsub!('template-id', template_id)

File.write(file_path, content)
end
end
end
151 changes: 151 additions & 0 deletions app/services/webforms/eg001_create_instance_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# frozen_string_literal: true

class Webforms::Eg001CreateInstanceService
attr_reader :args

include ApiCreator

def initialize(args)
@args = args
end

def create_web_form_template
templates_api = create_template_api args

options = DocuSign_eSign::ListTemplatesOptions.new
options.search_text = args[:template_name]
web_forms_templates = templates_api.list_templates(args[:account_id], options)

if web_forms_templates.result_set_size.to_i.positive?
template_id = web_forms_templates.envelope_templates[0].template_id
else
template_req_object = make_web_forms_template
template = templates_api.create_template(args[:account_id], template_req_object)
template_id = template.template_id
end

template_id
end

def list_web_forms
configuration = DocuSign_WebForms::Configuration.new

api_client = DocuSign_WebForms::ApiClient.new(configuration)
api_client.set_default_header('Authorization', "Bearer #{args[:access_token]}")

webforms_api = DocuSign_WebForms::FormManagementApi.new(api_client)

options = DocuSign_WebForms::ListFormsOptions.new
options.search = args[:form_name]

webforms_api.list_forms(args[:account_id], options)
end

def create_web_form_instance(form_id)
configuration = DocuSign_WebForms::Configuration.new

api_client = DocuSign_WebForms::ApiClient.new(configuration)
api_client.set_default_header('Authorization', "Bearer #{args[:access_token]}")

webforms_api = DocuSign_WebForms::FormInstanceManagementApi.new(api_client)

web_form_values = {
'PhoneNumber' => '555-555-5555',
'Yes' => ['Yes'],
'Company' => 'Tally',
'JobTitle' => 'Programmer Writer'
}
web_form_req_object = DocuSign_WebForms::CreateInstanceRequestBody.new({
'clientUserId' => args[:client_user_id],
'formValues' => web_form_values,
'expirationOffset' => '3600'
})
webforms_api.create_instance(args[:account_id], form_id, web_form_req_object)
end

private

def make_web_forms_template
template_name = args[:template_name]
doc_file = 'World_Wide_Corp_Web_Form.pdf'
base64_file_content = Base64.encode64(File.binread(File.join('data', doc_file)))

# Create the document model
document = DocuSign_eSign::Document.new({
# Create the DocuSign document object
'documentBase64' => base64_file_content,
'name' => 'World_Wide_Web_Form', # Can be different from actual file name
'fileExtension' => 'pdf', # Many different document types are accepted
'documentId' => '1' # A label used to reference the doc
})

# Create the signer recipient model
# Since these are role definitions, no name/email:
signer = DocuSign_eSign::Signer.new({
'roleName' => 'signer', 'recipientId' => '1', 'routingOrder' => '1'
})
# Create fields using absolute positioning
# Create a sign_here tab (field on the document)
sign_here = DocuSign_eSign::SignHere.new(
'documentId' => '1', 'tabLabel' => 'Signature',
'anchorString' => '/SignHere/', 'anchorUnits' => 'pixel',
'anchorXOffset' => '20', 'anchorYOffset' => '10'
)
check = DocuSign_eSign::Checkbox.new(
'documentId' => '1', 'tabLabel' => 'Yes',
'anchorString' => '/SMS/', 'anchorUnits' => 'pixel',
'anchorXOffset' => '20', 'anchorYOffset' => '10'
)
text1 = DocuSign_eSign::Text.new(
'documentId' => '1', 'tabLabel' => 'FullName',
'anchorString' => '/FullName/', 'anchorUnits' => 'pixel',
'anchorXOffset' => '20', 'anchorYOffset' => '10'
)
text2 = DocuSign_eSign::Text.new(
'documentId' => '1', 'tabLabel' => 'PhoneNumber',
'anchorString' => '/PhoneNumber/', 'anchorUnits' => 'pixel',
'anchorXOffset' => '20', 'anchorYOffset' => '10'
)
text3 = DocuSign_eSign::Text.new(
'documentId' => '1', 'tabLabel' => 'Company',
'anchorString' => '/Company/', 'anchorUnits' => 'pixel',
'anchorXOffset' => '20', 'anchorYOffset' => '10'
)
text4 = DocuSign_eSign::Text.new(
'documentId' => '1', 'tabLabel' => 'JobTitle',
'anchorString' => '/JobTitle/', 'anchorUnits' => 'pixel',
'anchorXOffset' => '20', 'anchorYOffset' => '10'
)
date_signed = DocuSign_eSign::DateSigned.new(
'documentId' => '1', 'tabLabel' => 'DateSigned',
'anchorString' => '/Date/', 'anchorUnits' => 'pixel',
'anchorXOffset' => '20', 'anchorYOffset' => '10'
)

# Add the tabs model to the signer
# The Tabs object takes arrays of the different field/tab types
signer.tabs = DocuSign_eSign::Tabs.new(
'signHereTabs' => [sign_here],
'checkboxTabs' => [check],
'textTabs' => [text1, text2, text3, text4],
'dateSignedTabs' => [date_signed]
)
# Create top two objects
envelope_template_definition = DocuSign_eSign::EnvelopeTemplate.new(
'description' => 'Example template created via the API',
'shared' => 'false'
)

# Top object:
DocuSign_eSign::EnvelopeTemplate.new(
'documents' => [document],
'name' => template_name,
'emailSubject' => 'Please sign this document',
'envelopeTemplateDefinition' => envelope_template_definition,
'recipients' => DocuSign_eSign::Recipients.new(
'signers' => [signer]
),
'status' => 'created'
)
end
end
2 changes: 2 additions & 0 deletions app/views/ds_common/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
"m"
elsif api["Name"] == "Connect"
"cn"
elsif api["Name"] == "WebForms"
"w"
else
"e"
end %>
Expand Down
5 changes: 5 additions & 0 deletions app/views/webforms/weg001_create_instance/get.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<%= render('partials/example_info') %>

<form class="eg" id="data_form" action="" method="post" data-busy="form">
<%= render('partials/submit_button') %>
</form>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<h4><%= @title %></h4>
<p><%= sanitize @description %></p>

<form class="eg" id="data_form" action="" method="post" data-busy="form">
<%= render('partials/submit_button') %>
</form>
Loading

0 comments on commit 6897222

Please sign in to comment.