Skip to content

Commit 074802a

Browse files
Added responsive signing example (#65)
* added the responsive signing example * update tabs * update file read and text changes Co-authored-by: Karissa Jacobsen <karissa.jacobsen@docusign.com>
1 parent ce63c76 commit 074802a

File tree

5 files changed

+213
-2
lines changed

5 files changed

+213
-2
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# frozen_string_literal: true
2+
3+
class ESign::Eg038ResponsiveSigningController < EgController
4+
before_action :check_auth
5+
6+
def create
7+
begin
8+
args = {
9+
account_id: session[:ds_account_id],
10+
base_path: session[:ds_base_path],
11+
access_token: session[:ds_access_token],
12+
signer_email: param_gsub(params[:signerEmail]),
13+
signer_name: param_gsub(params[:signerName]),
14+
cc_email: param_gsub(params[:ccEmail]),
15+
cc_name: param_gsub(params[:ccName]),
16+
ds_ping_url: Rails.application.config.app_url,
17+
signer_client_id: 1000,
18+
doc_file: 'data/order_form.html'
19+
}
20+
21+
redirect_url = ESign::Eg038ResponsiveSigningService.new(args).worker
22+
redirect_to redirect_url
23+
rescue DocuSign_eSign::ApiError => e
24+
handle_error(e)
25+
end
26+
end
27+
end
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# frozen_string_literal: true
2+
3+
class ESign::Eg038ResponsiveSigningService
4+
attr_reader :args
5+
include ApiCreator
6+
7+
def initialize(args)
8+
@args = args
9+
end
10+
11+
# ***DS.snippet.0.start
12+
def worker
13+
ds_return_url = "#{args[:ds_ping_url]}/ds_common-return"
14+
15+
# Step 1. Create the envelope definition
16+
envelope = make_envelope(args)
17+
18+
# Step 2. Call DocuSign to create the envelope
19+
envelope_api = create_envelope_api(args)
20+
21+
results = envelope_api.create_envelope args[:account_id], envelope
22+
envelope_id = results.envelope_id
23+
# Save for future use within the example launcher
24+
# session[:envelope_id] = envelope_id
25+
26+
# Step 3. Create the recipient view for the embedded signing
27+
view_request = make_recipient_view_request(args, ds_return_url)
28+
29+
# Call the CreateRecipientView API
30+
results = envelope_api.create_recipient_view args[:account_id], envelope_id, view_request
31+
32+
# Step 4. Redirect the user to the embedded signing
33+
# Don't use an iframe!
34+
# State can be stored/recovered using the framework's session or a
35+
# query parameter on the returnUrl (see the makeRecipientViewRequest method)
36+
# Redirect to results.url
37+
results.url
38+
end
39+
40+
private
41+
42+
def make_recipient_view_request(args, ds_return_url)
43+
view_request = DocuSign_eSign::RecipientViewRequest.new
44+
# Set the URL where you want the recipient to go once they are done signing
45+
# should typically be a callback route somewhere in your app.
46+
# The query parameter is included as an example of how
47+
# to save/recover state information during the redirect to
48+
# the DocuSign signing. It's usually better to use
49+
# the session mechanism of your web framework. Query parameters
50+
# can be changed/spoofed very easily.
51+
view_request.return_url = ds_return_url + '?state=123'
52+
53+
# How has your app authenticated the user? In addition to your app's
54+
# authentication, you can include authenticate steps from DocuSign;
55+
# e.g., SMS authentication
56+
view_request.authentication_method = 'none'
57+
58+
# Recipient information must match the embedded recipient info
59+
# that was used to create the envelope
60+
view_request.email = args[:signer_email]
61+
view_request.user_name = args[:signer_name]
62+
view_request.client_user_id = args[:signer_client_id]
63+
64+
# DocuSign recommends that you redirect to DocuSign for the embedded signing. There are
65+
# multiple ways to save state. To maintain your application's session, use the pingUrl
66+
# parameter. It causes the DocuSign signing web page (not the DocuSign server)
67+
# to send pings via AJAX to your app
68+
view_request.ping_frequency = '600' # seconds
69+
# NOTE: The pings will only be sent if the pingUrl is an HTTPS address
70+
view_request.ping_url = args[:ds_ping_url] # Optional setting
71+
72+
view_request
73+
end
74+
75+
def make_envelope(args)
76+
envelope_definition = DocuSign_eSign::EnvelopeDefinition.new
77+
envelope_definition.email_subject = 'Example Signing Document'
78+
79+
html_definition = DocuSign_eSign::DocumentHtmlDefinition.new
80+
html_definition.source = get_html_content(args)
81+
82+
doc = DocuSign_eSign::Document.new
83+
doc.name = 'doc1.html'
84+
doc.document_id = '1'
85+
doc.html_definition = html_definition
86+
87+
# The order in the docs array determines the order in the envelope
88+
envelope_definition.documents = [doc]
89+
# Create a signer recipient to sign the document, identified by name and email
90+
# We're setting the parameters via the object creation
91+
signer = DocuSign_eSign::Signer.new ({
92+
email: args[:signer_email],
93+
name: args[:signer_name],
94+
clientUserId: args[:signer_client_id],
95+
recipientId: 1,
96+
role_name: "Signer"
97+
})
98+
99+
cc = DocuSign_eSign::CarbonCopy.new ({
100+
email: args[:cc_email], name: args[:cc_name], recipientId: 2
101+
})
102+
103+
# Add the recipients to the envelope object
104+
recipients = DocuSign_eSign::Recipients.new
105+
recipients.signers = [signer]
106+
recipients.carbon_copies = [cc]
107+
108+
envelope_definition.recipients = recipients
109+
# Request that the envelope be sent by setting status to "sent".
110+
# To request that the envelope be created as a draft, set status to "created"
111+
envelope_definition.status = 'sent'
112+
envelope_definition
113+
end
114+
115+
def get_html_content(args)
116+
doc_html = File.open(args[:doc_file]).read
117+
# Substitute values into the HTML
118+
# Substitute for: {signerName}, {signerEmail}, {ccName}, {ccEmail}
119+
return doc_html.gsub('{signerName}', args[:signer_name]) \
120+
.gsub('{signerEmail}', args[:signer_email]) \
121+
.gsub('{ccName}', args[:cc_name]) \
122+
.gsub('{ccEmail}', args[:cc_email]) \
123+
.gsub("/sn1/", "<ds-signature data-ds-role=\"Signer\"/>") \
124+
.gsub("/l1q/", "<input data-ds-type=\"number\"/>") \
125+
.gsub("/l2q/", "<input data-ds-type=\"number\"/>")
126+
127+
end
128+
# ***DS.snippet.0.end
129+
end

app/views/ds_common/index.html.erb

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,18 @@
318318
<a target='_blank'
319319
href="https://developers.docusign.com/docs/esign-rest-api/reference/envelopes/envelopes/create/">Envelopes::create</a>.
320320
</p>
321-
</div>
322321

323-
<!-- anchor-js is only for the index page -->
322+
<h4 id="example038">38. <a href="eg038">Create a signable HTML document</a></h4>
323+
<p>
324+
Demonstrates how to create an HTML document for responsive signing.
325+
<p>
326+
API methods used:
327+
<a target="_blank" href="https://developers.docusign.com/docs/esign-rest-api/reference/envelopes/envelopes/create/">Envelopes::create</a>,
328+
<a target='_blank'
329+
href="https://developers.docusign.com/docs/esign-rest-api/reference/envelopes/envelopeviews/createrecipient/">EnvelopeViews::createRecipient</a>.
330+
</p>
331+
</div>
332+
333+
<!-- anchor-js is only for the index page -->
324334
<script src="https://cdnjs.cloudflare.com/ajax/libs/anchor-js/4.1.1/anchor.min.js"></script>
325335
<script>anchors.options.placement = 'left'; anchors.add('h4')</script>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<h4>38. Create a signable HTML document</h4>
2+
<p>Demonstrates how to create an HTML document for responsive signing.</p>
3+
4+
<% if @show_doc %>
5+
<p><a target='_blank' href='<%= @documentation %>'>Documentation</a> about this example.</p>
6+
<% end %>
7+
8+
<p>API method used:
9+
<a target ='_blank' href="https://developers.docusign.com/docs/esign-rest-api/reference/envelopes/envelopes/create/">Envelopes::create</a> and
10+
<a target ='_blank' href="https://developers.docusign.com/docs/esign-rest-api/reference/envelopes/envelopeviews/createrecipient/">EnvelopeViews::createRecipient</a>.
11+
</p>
12+
13+
<p>
14+
View source file <a target="_blank" href="<%= @source_url %>"><%= @source_file %></a> on GitHub.
15+
</p>
16+
17+
<form class="eg" action="" method="post" data-busy="form">
18+
<div class="form-group">
19+
<label for="signerEmail">Signer Email</label>
20+
<input type="email" class="form-control" id="signerEmail" name="signerEmail"
21+
aria-describedby="emailHelp" placeholder="pat@example.com" required
22+
value="<%= @config.signer_email %>">
23+
<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
24+
</div>
25+
<div class="form-group">
26+
<label for="signerName">Signer Name</label>
27+
<input type="text" class="form-control" id="signerName" placeholder="Pat Johnson" name="signerName"
28+
value="<%= @config.signer_name %>" required>
29+
</div>
30+
<div class="form-group">
31+
<label for="ccEmail">CC Email</label>
32+
<input type="email" class="form-control" id="ccEmail" name="ccEmail"
33+
aria-describedby="emailHelp" placeholder="pat@example.com" required />
34+
<small id="emailHelp" class="form-text text-muted">The email for the cc recipient must be different from the signer's email.</small>
35+
</div>
36+
<div class="form-group">
37+
<label for="ccName">CC Name</label>
38+
<input type="text" class="form-control" id="ccName" placeholder="Pat Johnson" name="ccName"
39+
required>
40+
</div>
41+
<button type="submit" class="btn btn-docu">Submit</button>
42+
</form>

config/routes.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@
185185

186186
get 'eg037' => 'eg037_sms_delivery#get'
187187
post 'eg037' => 'eg037_sms_delivery#create'
188+
189+
get 'eg038' => 'eg038_responsive_signing#get'
190+
post 'eg038' => 'eg038_responsive_signing#create'
188191
end
189192
end
190193

0 commit comments

Comments
 (0)