Skip to content

Commit dd66cd1

Browse files
author
Balaji Jayaraman
committed
workspace examples
1 parent ed55a52 commit dd66cd1

20 files changed

+615
-15
lines changed

demo_documents/Term_Of_Service.pdf

33 KB
Binary file not shown.
295 KB
Binary file not shown.

index.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ const { eg004notary } = require('./lib/notary/controllers');
6262
const { eg001fields } = require('./lib/connectedFields/controllers');
6363
const { eg001Navigator, eg002Navigator } = require('./lib/navigator/controllers');
6464
const { eg001maestro, eg002maestro, eg003maestro, eg004maestro } = require('./lib/maestro/controllers');
65+
const { eg001workspaces, eg002workspaces, eg003workspaces } = require('./lib/workspaces/controllers');
6566

6667
const PORT = process.env.PORT || 3000;
6768
const HOST = process.env.HOST || 'localhost';
@@ -319,6 +320,13 @@ app.get('/mae001', eg001maestro.getController)
319320
.get('/mae004', eg004maestro.getController)
320321
.post('/mae004', eg004maestro.createController);
321322

323+
app.get('/work001', eg001workspaces.getController)
324+
.post('/work001', eg001workspaces.createController)
325+
.get('/work002', eg002workspaces.getController)
326+
.post('/work002', eg002workspaces.createController)
327+
.get('/work003', eg003workspaces.getController)
328+
.post('/work003', eg003workspaces.createController);
329+
322330
function dsLoginCB1(req, res, next) { req.dsAuthCodeGrant.oauth_callback1(req, res, next); }
323331
function dsLoginCB2(req, res, next) { req.dsAuthCodeGrant.oauth_callback2(req, res, next); }
324332

lib/eSignature/examples/createTemplate.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,8 @@ const createTemplate = async (args) => {
4545
});
4646
//ds-snippet-end:eSign8Step3
4747
createdNewTemplate = true;
48-
// Retrieve the new template Name / TemplateId
49-
results = await templatesApi.listTemplates(args.accountId, {
50-
searchText: args.templateName,
51-
});
52-
templateId = results.envelopeTemplates[0].templateId;
53-
resultsTemplateName = results.envelopeTemplates[0].name;
48+
templateId = results.templateId;
49+
resultsTemplateName = results.name;
5450
}
5551

5652
return {

lib/utils.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const API_TYPES = {
2626
CONNECTED_FIELDS: 'ConnectedFields',
2727
NAVIGATOR: 'Navigator',
2828
MAESTRO: 'Maestro',
29+
WORKSPACES: 'Workspaces',
2930
};
3031

3132
async function isCFR(accessToken, accountId, basePath) {
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/**
2+
* @file
3+
* Example 001: Create a workspace
4+
* @author DocuSign
5+
*/
6+
7+
const path = require('path');
8+
const { createWorkspace } = require('../../workspaces/examples/createWorkspace');
9+
const validator = require('validator');
10+
const { getExampleByNumber } = require('../../manifestService');
11+
const dsConfig = require('../../../config/index').config;
12+
const { API_TYPES, formatString } = require('../../utils');
13+
14+
const eg001CreateWorkspace = exports;
15+
const exampleNumber = 1;
16+
const eg = `work00${exampleNumber}`; // This example reference.
17+
const api = API_TYPES.WORKSPACES;
18+
const mustAuthenticate = '/ds/mustAuthenticate';
19+
const minimumBufferMin = 3;
20+
/**
21+
* Create a workspace
22+
* @param {object} req Request obj
23+
* @param {object} res Response obj
24+
*/
25+
eg001CreateWorkspace.createController = async (req, res) => {
26+
// Step 1. Check the token
27+
// At this point we should have a good token. But we
28+
// double-check here to enable a better UX to the user.
29+
const isTokenOK = req.dsAuth.checkToken(minimumBufferMin);
30+
if (!isTokenOK) {
31+
req.flash('info', 'Sorry, you need to re-authenticate.');
32+
// Save the current operation so it will be resumed after authentication
33+
req.dsAuth.setEg(req, eg);
34+
return res.redirect(mustAuthenticate);
35+
}
36+
37+
// Step 2. Call the worker method
38+
const { body } = req;
39+
const args = {
40+
accessToken: req.user.accessToken,
41+
basePath: req.session.basePath,
42+
accountId: req.session.accountId,
43+
workspaceName: validator.escape(body.workspaceName),
44+
};
45+
let results = null;
46+
47+
try {
48+
results = await createWorkspace(args);
49+
} catch (error) {
50+
const errorBody = error?.body || error?.response?.body;
51+
// we can pull the DocuSign error code and message from the response body
52+
const errorCode = errorBody?.errorCode;
53+
const errorMessage = errorBody?.message;
54+
// In production, may want to provide customized error messages and
55+
// remediation advice to the user.
56+
res.render('pages/error', { err: error, errorCode, errorMessage });
57+
}
58+
if (results) {
59+
req.session.workspaceId = results.workspaceId;
60+
61+
const example = getExampleByNumber(res.locals.manifest, exampleNumber, api);
62+
res.render('pages/example_done', {
63+
title: example.ExampleName,
64+
message: formatString(example.ResultsPageText, results.workspaceId),
65+
json: JSON.stringify(results),
66+
});
67+
}
68+
};
69+
70+
/**
71+
* Form page for this application
72+
*/
73+
eg001CreateWorkspace.getController = async (req, res) => {
74+
// Check that the authentication token is ok with a long buffer time.
75+
// If needed, now is the best time to ask the user to authenticate
76+
// since they have not yet entered any information into the form.
77+
const isTokenOK = req.dsAuth.checkToken();
78+
if (!isTokenOK) {
79+
// Save the current operation so it will be resumed after authentication
80+
req.dsAuth.setEg(req, eg);
81+
return res.redirect(mustAuthenticate);
82+
}
83+
84+
const example = getExampleByNumber(res.locals.manifest, exampleNumber, api);
85+
const sourceFile = (path.basename(__filename))[5].toLowerCase() + (path.basename(__filename)).substr(6);
86+
res.render('pages/workspaces-examples/eg001CreateWorkspace', {
87+
eg: eg,
88+
csrfToken: req.csrfToken(),
89+
example: example,
90+
sourceFile: sourceFile,
91+
sourceUrl: dsConfig.githubExampleUrl + 'workspaces/examples/' + sourceFile,
92+
documentation: dsConfig.documentation + eg,
93+
showDoc: dsConfig.documentation
94+
});
95+
};
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/**
2+
* @file
3+
* Example 002: Add a document to a Workspace
4+
* @author DocuSign
5+
*/
6+
7+
const path = require('path');
8+
const { addDocumentToWorkspace } = require('../../workspaces/examples/addDocumentToWorkspace');
9+
const validator = require('validator');
10+
const { getExampleByNumber } = require('../../manifestService');
11+
const dsConfig = require('../../../config/index').config;
12+
const { formatString, API_TYPES } = require('../../utils');
13+
14+
const eg002AddDocumentToWorkspace = exports;
15+
const exampleNumber = 2;
16+
const eg = `work00${exampleNumber}`; // This example reference.
17+
const api = API_TYPES.WORKSPACES;
18+
const mustAuthenticate = '/ds/mustAuthenticate';
19+
const minimumBufferMin = 3;
20+
const demoDocsPath = path.resolve(__dirname, '../../../demo_documents');
21+
22+
/**
23+
* Add a document to a workspace
24+
* @param {object} req Request obj
25+
* @param {object} res Response obj
26+
*/
27+
eg002AddDocumentToWorkspace.createController = async (req, res) => {
28+
// Step 1. Check the token
29+
// At this point we should have a good token. But we
30+
// double-check here to enable a better UX to the user.
31+
const isTokenOK = req.dsAuth.checkToken(minimumBufferMin);
32+
if (!isTokenOK) {
33+
req.flash('info', 'Sorry, you need to re-authenticate.');
34+
// Save the current operation so it will be resumed after authentication
35+
req.dsAuth.setEg(req, eg);
36+
return res.redirect(mustAuthenticate);
37+
}
38+
39+
// Step 2. Call the worker method
40+
const { body } = req;
41+
const documentPath = validator.escape(body.documentPath);
42+
const args = {
43+
accessToken: req.user.accessToken,
44+
basePath: req.session.basePath,
45+
accountId: req.session.accountId,
46+
workspaceId: req.session.workspaceId,
47+
documentPath: path.resolve(demoDocsPath, documentPath),
48+
documentName: validator.escape(body.documentName),
49+
};
50+
let results = null;
51+
52+
try {
53+
results = await addDocumentToWorkspace(args);
54+
} catch (error) {
55+
const errorBody = error?.body || error?.response?.body;
56+
// we can pull the DocuSign error code and message from the response body
57+
const errorCode = errorBody?.errorCode;
58+
const errorMessage = errorBody?.message;
59+
// In production, may want to provide customized error messages and
60+
// remediation advice to the user.
61+
res.render('pages/error', { err: error, errorCode, errorMessage });
62+
}
63+
if (results) {
64+
req.session.documentId = results.documentId;
65+
66+
const example = getExampleByNumber(res.locals.manifest, exampleNumber, api);
67+
res.render('pages/example_done', {
68+
title: example.ExampleName,
69+
message: formatString(example.ResultsPageText, results.documentId),
70+
json: JSON.stringify(results),
71+
});
72+
}
73+
};
74+
75+
/**
76+
* Form page for this application
77+
*/
78+
eg002AddDocumentToWorkspace.getController = async (req, res) => {
79+
// Check that the authentication token is ok with a long buffer time.
80+
// If needed, now is the best time to ask the user to authenticate
81+
// since they have not yet entered any information into the form.
82+
const isTokenOK = req.dsAuth.checkToken();
83+
if (!isTokenOK) {
84+
// Save the current operation so it will be resumed after authentication
85+
req.dsAuth.setEg(req, eg);
86+
return res.redirect(mustAuthenticate);
87+
}
88+
89+
const example = getExampleByNumber(res.locals.manifest, exampleNumber, api);
90+
const sourceFile = (path.basename(__filename))[5].toLowerCase() + (path.basename(__filename)).substr(6);
91+
res.render('pages/workspaces-examples/eg002AddDocumentToWorkspace', {
92+
eg: eg,
93+
csrfToken: req.csrfToken(),
94+
workspaceIdOk: !!req.session.workspaceId,
95+
documentFolder: formatString(res.locals.manifest.SupportingTexts.HelpingTexts.SelectPDFFileFromFolder, demoDocsPath),
96+
example: example,
97+
sourceFile: sourceFile,
98+
sourceUrl: dsConfig.githubExampleUrl + 'workspaces/examples/' + sourceFile,
99+
documentation: dsConfig.documentation + eg,
100+
showDoc: dsConfig.documentation
101+
});
102+
};
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/**
2+
* @file
3+
* Example 003: Send an Workspace Envelope with Recipient Info
4+
* @author DocuSign
5+
*/
6+
7+
const path = require('path');
8+
const { createEnvelope, sendEnvelope } = require('../../workspaces/examples/sendEnvelopeWithRecipientInfo');
9+
const validator = require('validator');
10+
const { getExampleByNumber } = require('../../manifestService');
11+
const dsConfig = require('../../../config/index').config;
12+
const { API_TYPES } = require('../../utils');
13+
14+
const eg003SendEnvelopeWithRecipientInfo = exports;
15+
const exampleNumber = 3;
16+
const eg = `work00${exampleNumber}`; // This example reference.
17+
const api = API_TYPES.WORKSPACES;
18+
const mustAuthenticate = '/ds/mustAuthenticate';
19+
const minimumBufferMin = 3;
20+
/**
21+
* Send an Workspace Envelope with Recipient Info
22+
* @param {object} req Request obj
23+
* @param {object} res Response obj
24+
*/
25+
eg003SendEnvelopeWithRecipientInfo.createController = async (req, res) => {
26+
// Step 1. Check the token
27+
// At this point we should have a good token. But we
28+
// double-check here to enable a better UX to the user.
29+
const isTokenOK = req.dsAuth.checkToken(minimumBufferMin);
30+
if (!isTokenOK) {
31+
req.flash('info', 'Sorry, you need to re-authenticate.');
32+
// Save the current operation so it will be resumed after authentication
33+
req.dsAuth.setEg(req, eg);
34+
return res.redirect(mustAuthenticate);
35+
}
36+
37+
// Step 2. Call the worker method
38+
const { body } = req;
39+
const args = {
40+
accessToken: req.user.accessToken,
41+
basePath: req.session.basePath,
42+
accountId: req.session.accountId,
43+
workspaceId: req.session.workspaceId,
44+
documentId: req.session.documentId,
45+
signerEmail: validator.escape(body.signerEmail),
46+
signerName: validator.escape(body.signerName),
47+
};
48+
let results = null;
49+
50+
try {
51+
const workspaceEnvelope = await createEnvelope(args);
52+
results = await sendEnvelope({ ...args, envelopeId: workspaceEnvelope.envelopeId });
53+
} catch (error) {
54+
const errorBody = error?.body || error?.response?.body;
55+
// we can pull the DocuSign error code and message from the response body
56+
const errorCode = errorBody?.errorCode;
57+
const errorMessage = errorBody?.message;
58+
// In production, may want to provide customized error messages and
59+
// remediation advice to the user.
60+
res.render('pages/error', { err: error, errorCode, errorMessage });
61+
}
62+
if (results) {
63+
const example = getExampleByNumber(res.locals.manifest, exampleNumber, api);
64+
res.render('pages/example_done', {
65+
title: example.ExampleName,
66+
message: formatString(example.ResultsPageText, results.envelopeId),
67+
});
68+
}
69+
};
70+
71+
/**
72+
* Form page for this application
73+
*/
74+
eg003SendEnvelopeWithRecipientInfo.getController = async (req, res) => {
75+
// Check that the authentication token is ok with a long buffer time.
76+
// If needed, now is the best time to ask the user to authenticate
77+
// since they have not yet entered any information into the form.
78+
const isTokenOK = req.dsAuth.checkToken();
79+
if (!isTokenOK) {
80+
// Save the current operation so it will be resumed after authentication
81+
req.dsAuth.setEg(req, eg);
82+
return res.redirect(mustAuthenticate);
83+
}
84+
85+
const example = getExampleByNumber(res.locals.manifest, exampleNumber, api);
86+
const sourceFile = (path.basename(__filename))[5].toLowerCase() + (path.basename(__filename)).substr(6);
87+
res.render('pages/workspaces-examples/eg003SendEnvelopeWithRecipientInfo', {
88+
eg: eg,
89+
csrfToken: req.csrfToken(),
90+
workspaceIdOk: !!req.session.workspaceId,
91+
documentIdOk: !!req.session.documentId,
92+
example: example,
93+
sourceFile: sourceFile,
94+
sourceUrl: dsConfig.githubExampleUrl + 'workspaces/examples/' + sourceFile,
95+
documentation: dsConfig.documentation + eg,
96+
showDoc: dsConfig.documentation
97+
});
98+
};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports.eg001workspaces = require('./eg001CreateWorkspace');
2+
module.exports.eg002workspaces = require('./eg002AddDocumentToWorkspace');
3+
module.exports.eg003workspaces = require('./eg003SendEnvelopeWithRecipientInfo');
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* @file
3+
* Example 002: Add a document to a Workspaces
4+
* @author DocuSign
5+
*/
6+
7+
const iam = require('@docusign/iam-sdk');
8+
const fs = require('fs').promises;
9+
10+
const addDocumentToWorkspace = async (args) => {
11+
//ds-snippet-start:Workspaces2Step2
12+
const client = new iam.IamClient({ accessToken: args.accessToken });
13+
//ds-snippet-end:Workspaces2Step2
14+
15+
//ds-snippet-start:Workspaces2Step3
16+
const buffer = await fs.readFile(args.documentPath);
17+
const uint8array = new Uint8Array(
18+
buffer.buffer,
19+
buffer.byteOffset,
20+
buffer.byteLength
21+
);
22+
const addWorkspaceDocumentRequest = {
23+
file: {
24+
fileName: args.documentName,
25+
content: uint8array,
26+
},
27+
};
28+
//ds-snippet-end:Workspaces2Step3
29+
30+
//ds-snippet-start:Workspaces2Step4
31+
return await client.workspaces1.workspaceDocuments.addWorkspaceDocument({
32+
accountId: args.accountId,
33+
workspaceId: args.workspaceId,
34+
addWorkspaceDocumentRequest,
35+
});
36+
//ds-snippet-end:Workspaces2Step4
37+
};
38+
39+
module.exports = { addDocumentToWorkspace };

0 commit comments

Comments
 (0)