Skip to content

Commit

Permalink
eg 17
Browse files Browse the repository at this point in the history
  • Loading branch information
LarryKlugerDS committed Dec 10, 2018
1 parent 4a74c72 commit 136a0df
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 3 deletions.
3 changes: 3 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const express = require('express')
, eg014 = require('./lib/examples/eg014CollectPayment')
, eg015 = require('./lib/examples/eg015EnvelopeTabData')
, eg016 = require('./lib/examples/eg016SetTabValues')
, eg017 = require('./lib/examples/eg017SetTemplateTabValues')
, eg018 = require('./lib/examples/eg018EnvelopeCustomFieldData')
;

Expand Down Expand Up @@ -138,6 +139,8 @@ let app = express()
.post('/eg015', eg015.createController)
.get('/eg016', eg016.getController)
.post('/eg016', eg016.createController)
.get('/eg017', eg017.getController)
.post('/eg017', eg017.createController)
.get('/eg018', eg018.getController)
.post('/eg018', eg018.createController)
;
Expand Down
249 changes: 249 additions & 0 deletions lib/examples/eg017SetTemplateTabValues.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
/**
* @file
* Example 017: Set template tab (field) values and an envelope custom field value
* @author DocuSign
*/

const path = require('path')
, docusign = require('docusign-esign')
, validator = require('validator')
, dsConfig = require('../../ds_configuration.js').config
;

const eg017SetTemplateTabValues = exports
, eg = 'eg017' // This example reference.
, mustAuthenticate = '/ds/mustAuthenticate'
, minimumBufferMin = 3
;


/**
* Send envelope with a template
* @param {object} req Request obj
* @param {object} res Response obj
*/
eg017SetTemplateTabValues.createController = async (req, res) => {
// Step 1. Check the token
// At this point we should have a good token. But we
// double-check here to enable a better UX to the user.
let tokenOK = req.dsAuthCodeGrant.checkToken(minimumBufferMin);
if (! tokenOK) {
req.flash('info', 'Sorry, you need to re-authenticate.');
// We could store the parameters of the requested operation
// so it could be restarted automatically.
// But since it should be rare to have a token issue here,
// we'll make the user re-enter the form data after
// authentication.
req.dsAuthCodeGrant.setEg(req, eg);
res.redirect(mustAuthenticate);
}

if (!req.session.templateId) {
res.render('pages/examples/eg017SetTemplateTabValues', {
csrfToken: req.csrfToken(),
title: "Send envelope using a template",
templateOk: req.session.templateId,
sourceFile: path.basename(__filename),
sourceUrl: dsConfig.githubExampleUrl + path.basename(__filename),
documentation: dsConfig.documentation + eg,
showDoc: dsConfig.documentation
});
}

// Step 2. Call the worker method
let body = req.body
// Additional data validation might also be appropriate
, signerEmail = validator.escape(body.signerEmail)
, signerName = validator.escape(body.signerName)
, ccEmail = validator.escape(body.ccEmail)
, ccName = validator.escape(body.ccName)
, envelopeArgs = {
templateId: req.session.templateId,
signerEmail: signerEmail,
signerName: signerName,
signerClientId: 1000,
ccEmail: ccEmail,
ccName: ccName,
dsReturnUrl: dsConfig.appUrl + '/ds-return'
}
, args = {
accessToken: req.user.accessToken,
basePath: req.session.basePath,
accountId: req.session.accountId,
envelopeArgs: envelopeArgs
}
, results = null
;

try {
results = await eg017SetTemplateTabValues.worker (args)
}
catch (error) {
let errorBody = error && error.response && error.response.body
// we can pull the DocuSign error code and message from the response body
, errorCode = errorBody && errorBody.errorCode
, errorMessage = errorBody && errorBody.message
;
// In production, may want to provide customized error messages and
// remediation advice to the user.
res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage});
}
if (results) {
req.session.envelopeId = results.envelopeId; // Save for use by other examples
// which need an envelopeId
// Redirect the user to the Signing Ceremony
// Don't use an iFrame!
// State can be stored/recovered using the framework's session or a
// query parameter on the returnUrl (see the makeRecipientViewRequest method)
res.redirect(results.redirectUrl);
}
}

/**
* This function does the work of creating the envelope
* @param {object} args
*/
// ***DS.worker.start ***DS.snippet.1.start
eg017SetTemplateTabValues.worker = async (args) => {
// 1. Create envelope definition
let envelopeArgs = args.envelopeArgs
, envelopeDefinition = makeEnvelope(envelopeArgs);

// 2. Create the envelope
let dsApiClient = new docusign.ApiClient();
dsApiClient.setBasePath(args.basePath);
dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken);
let envelopesApi = new docusign.EnvelopesApi(dsApiClient)
, results = await envelopesApi.createEnvelope(
args.accountId, {envelopeDefinition: envelopeDefinition})
, envelopeId = results.envelopeId
;

// 3. create the recipient view, the Signing Ceremony
let viewRequest = docusign.RecipientViewRequest.constructFromObject({
returnUrl: envelopeArgs.dsReturnUrl,
authenticationMethod: 'none',
email: envelopeArgs.signerEmail,
userName: envelopeArgs.signerName,
clientUserId: envelopeArgs.signerClientId});

// 4. Call the CreateRecipientView API
// Exceptions will be caught by the calling function
results = await envelopesApi.createRecipientView(args.accountId, envelopeId,
{recipientViewRequest: viewRequest});

return ({envelopeId: envelopeId, redirectUrl: results.url})
}
// ***DS.worker.end ***DS.snippet.1.end

// ***DS.snippet.2.start
/**
* Creates envelope from the template
* @function
* @param {Object} args
* @returns {Envelope} An envelope definition
* @private
*/
function makeEnvelope(args){
// The envelope has two recipients.
// recipient 1 - signer
// recipient 2 - cc
// This method sets values for many of the template's tabs.
// It also adds a new tab, and adds a custom metadata field

// create the envelope definition with the template id
let envelopeDefinition = docusign.EnvelopeDefinition.constructFromObject({
templateId: args.templateId, status: 'sent'
});

// Set the values for the fields in the template
// List item
let list1 = docusign.List.constructFromObject({
value: "green", documentId: "1", pageNumber: "1", tabLabel: "list"});

// Checkboxes
let check1 = docusign.Checkbox.constructFromObject({
tabLabel: 'ckAuthorization', selected: "true"})
, check3 = docusign.Checkbox.constructFromObject({
tabLabel: 'ckAgreement', selected: "true"});
// The NOde.js SDK has a bug so it cannot create a Number tab at this time.
//number1 = docusign.Number.constructFromObject({
// tabLabel: "numbersOnly", value: '54321'});
let radioGroup = docusign.RadioGroup.constructFromObject({
groupName: "radio1",
// You only need to provide the radio entry for the entry you're selecting
radios:
[docusign.Radio.constructFromObject({value: "white", selected: "true"})]
});
let text = docusign.Text.constructFromObject({
tabLabel: "text", value: "Jabberwocky!"});

// We can also add a new tab (field) to the ones already in the template:
let textExtra = docusign.Text.constructFromObject({
document_id: "1", page_number: "1",
x_position: "280", y_position: "172",
font: "helvetica", font_size: "size14", tab_label: "added text field",
height: "23", width: "84", required: "false",
bold: 'true', value: args.signerName,
locked: 'false', tab_id: 'name'});

// Pull together the existing and new tabs in a Tabs object:
let tabs = docusign.Tabs.constructFromObject({
checkboxTabs: [check1, check3], // numberTabs: [number1],
radioGroupTabs: [radioGroup], textTabs: [text, textExtra],
listTabs: [list1]
});
// Create the template role elements to connect the signer and cc recipients
// to the template
let signer = docusign.TemplateRole.constructFromObject({
email: args.signerEmail, name: args.signerName,
roleName: 'signer',
clientUserId: args.signerClientId, // change the signer to be embedded
tabs: tabs // Set tab values
});
// Create a cc template role.
let cc = docusign.TemplateRole.constructFromObject({
email: args.ccEmail, name: args.ccName,
roleName: 'cc'
});
// Add the TemplateRole objects to the envelope object
envelopeDefinition.templateRoles = [signer, cc];
// Create an envelope custom field to save the our application's
// data about the envelope
let customField = docusign.TextCustomField.constructFromObject({
name: 'app metadata item',
required: 'false',
show: 'true', // Yes, include in the CoC
value: '1234567'})
, customFields = docusign.CustomFields.constructFromObject({
textCustomFields: [customField]});
envelopeDefinition.customFields = customFields;

return envelopeDefinition;
}
// ***DS.snippet.2.end

/**
* Form page for this application
*/
eg017SetTemplateTabValues.getController = (req, res) => {
// Check that the authentication token is ok with a long buffer time.
// If needed, now is the best time to ask the user to authenticate
// since they have not yet entered any information into the form.
let tokenOK = req.dsAuthCodeGrant.checkToken();
if (tokenOK) {
res.render('pages/examples/eg017SetTemplateTabValues', {
csrfToken: req.csrfToken(),
title: "Set template tab values",
templateOk: req.session.templateId,
sourceFile: path.basename(__filename),
sourceUrl: dsConfig.githubExampleUrl + path.basename(__filename),
documentation: dsConfig.documentation + eg,
showDoc: dsConfig.documentation
});
} else {
// Save the current operation so it will be resumed after authentication
req.dsAuthCodeGrant.setEg(req, eg);
res.redirect(mustAuthenticate);
}
}
4 changes: 2 additions & 2 deletions views/pages/examples/eg017SetTemplateTabValues.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ radio button and checkbox tabs.</p>
<label for="signerEmail">Signer Email</label>
<input type="email" class="form-control" id="signerEmail" name="signerEmail"
aria-describedby="emailHelp" placeholder="pat@example.com" required
value="<%= signerEmail %>">
value="<%= locals.dsConfig.signerEmail %>">
<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div class="form-group">
<label for="signerName">Signer Name</label>
<input type="text" class="form-control" id="signerName" placeholder="Pat Johnson" name="signerName"
value="<%= signerName %>" required>
value="<%= locals.dsConfig.signerName %>" required>
</div>
<div class="form-group">
<label for="ccEmail">CC Email</label>
Expand Down
2 changes: 1 addition & 1 deletion views/pages/index.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@
<a target ='_blank' href="https://developers.docusign.com/esign-rest-api/reference/Envelopes/Envelopes/create">Envelopes::create</a>.
</p>

<h4 id="example017">17. <a href="eg017'">Set template tab values</a></h4>
<h4 id="example017">17. <a href="eg017">Set template tab values</a></h4>
<p>This example sets the tab (field) values for a template being used by an envelope.</p>
<p>API method used:
<a target ='_blank' href="https://developers.docusign.com/esign-rest-api/reference/Envelopes/Envelopes/create">Envelopes::create</a>.
Expand Down

0 comments on commit 136a0df

Please sign in to comment.