Skip to content

Commit f554aee

Browse files
authored
Merge pull request #223 from docusign/feature/delete-restore-envelope
Delete and Restore an Envelope Functionality works as expected
2 parents 5c87418 + 544e03e commit f554aee

File tree

12 files changed

+410
-97
lines changed

12 files changed

+410
-97
lines changed

index.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ const {
2929
eg016, eg017, eg018, eg019, eg020, eg022, eg023,
3030
eg024, eg025, eg026, eg027, eg028, eg029, eg030,
3131
eg031, eg032, eg033, eg034, eg035, eg036, eg037,
32-
eg038, eg039, eg040, eg041, eg042, eg043, eg044
32+
eg038, eg039, eg040, eg041, eg042, eg043, eg044,
33+
eg045
3334
} = require('./lib/eSignature/controllers');
3435

3536
const {
@@ -279,7 +280,11 @@ app.get('/eg001', eg001.getController)
279280
.get('/eg043envelopes', eg043.listEnvelopes)
280281
.post('/eg043', eg043.createController)
281282
.get('/eg044', eg044.getController)
282-
.post('/eg044', eg044.createController);
283+
.post('/eg044', eg044.createController)
284+
.get('/eg045', eg045.getDeleteController)
285+
.post('/eg045', eg045.deleteController)
286+
.get('/eg045restore', eg045.getRestoreController)
287+
.post('/eg045restore', eg045.restoreController);
283288

284289
app.get('/cneg001', eg001connect.getController)
285290
.post('/cneg001', eg001connect.createController);
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
/**
2+
* @file
3+
* Example 045: Delete and Undelete an Envelope
4+
* @author DocuSign
5+
*/
6+
7+
const path = require('path');
8+
const { moveEnvelope, getFolders } = require('../examples/deleteRestoreEnvelope');
9+
const { getExampleByNumber } = require('../../manifestService');
10+
const dsConfig = require('../../../config/index.js').config;
11+
const { API_TYPES, formatString } = require('../../utils.js');
12+
const { getFolderIdByName } = require('../getData.js');
13+
14+
const eg045DeleteRestoreEnvelope = exports;
15+
const exampleNumber = 45;
16+
const eg = `eg0${exampleNumber}`; // This example reference.
17+
const api = API_TYPES.ESIGNATURE;
18+
const mustAuthenticate = '/ds/mustAuthenticate';
19+
const minimumBufferMin = 3;
20+
const restoreEndpoint = `${eg}restore`;
21+
const deleteFolderId = 'recyclebin';
22+
23+
/**
24+
* Delete the envelope
25+
* @param {object} req Request obj
26+
* @param {object} res Response obj
27+
*/
28+
eg045DeleteRestoreEnvelope.deleteController = async (req, res) => {
29+
// Step 1. Check the token
30+
// At this point we should have a good token. But we
31+
// double-check here to enable a better UX to the user.
32+
const isTokenOK = req.dsAuth.checkToken(minimumBufferMin);
33+
if (!isTokenOK) {
34+
req.flash('info', 'Sorry, you need to re-authenticate.');
35+
// Save the current operation so it will be resumed after authentication
36+
req.dsAuth.setEg(req, eg);
37+
return res.redirect(mustAuthenticate);
38+
}
39+
40+
// Step 2. Call the worker method
41+
const args = {
42+
accessToken: req.user.accessToken,
43+
basePath: req.session.basePath,
44+
accountId: req.session.accountId,
45+
envelopeId: req.body.envelopeId,
46+
folderId: deleteFolderId,
47+
};
48+
let results = null;
49+
50+
try {
51+
results = await moveEnvelope(args);
52+
} catch (error) {
53+
const errorBody = error?.body || error?.response?.body;
54+
// we can pull the DocuSign error code and message from the response body
55+
const errorCode = errorBody?.errorCode;
56+
const errorMessage = errorBody?.message;
57+
// In production, may want to provide customized error messages and
58+
// remediation advice to the user.
59+
res.render('pages/error', {err: error, errorCode, errorMessage});
60+
}
61+
if (results) {
62+
req.session.envelopeId = req.body.envelopeId;
63+
64+
const example = getExampleByNumber(res.locals.manifest, exampleNumber, api);
65+
const additionalPageData = example.AdditionalPage.find(p => p.Name === 'envelope_is_deleted');
66+
res.render('pages/example_done', {
67+
title: example.ExampleName,
68+
message: formatString(additionalPageData.ResultsPageText, req.body.envelopeId),
69+
redirectUrl: restoreEndpoint,
70+
});
71+
}
72+
};
73+
74+
/**
75+
* Undelete the envelope
76+
* @param {object} req Request obj
77+
* @param {object} res Response obj
78+
*/
79+
eg045DeleteRestoreEnvelope.restoreController = async (req, res) => {
80+
// Step 1. Check the token
81+
// At this point we should have a good token. But we
82+
// double-check here to enable a better UX to the user.
83+
const isTokenOK = req.dsAuth.checkToken(minimumBufferMin);
84+
if (!isTokenOK) {
85+
req.flash('info', 'Sorry, you need to re-authenticate.');
86+
// Save the current operation so it will be resumed after authentication
87+
req.dsAuth.setEg(req, eg);
88+
return res.redirect(mustAuthenticate);
89+
}
90+
91+
const args = {
92+
accessToken: req.user.accessToken,
93+
basePath: req.session.basePath,
94+
accountId: req.session.accountId,
95+
envelopeId: req.session.envelopeId,
96+
fromFolderId: deleteFolderId,
97+
};
98+
const folderName = req.body.folderName;
99+
let folderId = '';
100+
101+
const example = getExampleByNumber(res.locals.manifest, exampleNumber, api);
102+
103+
// Step 2. Call the worker method
104+
let results = null;
105+
try {
106+
const folders = await getFolders(args);
107+
folderId = getFolderIdByName(folders.folders, folderName);
108+
109+
if (!folderId) {
110+
const additionalPageData = example.AdditionalPage.find(page => page.Name === 'folder_does_not_exist');
111+
return res.render('pages/example_done', {
112+
title: example.ExampleName,
113+
message: formatString(additionalPageData.ResultsPageText, folderName),
114+
redirectUrl: restoreEndpoint,
115+
});
116+
117+
}
118+
119+
results = await moveEnvelope({ ...args, folderId });
120+
} catch (error) {
121+
const errorBody = error?.body || error?.response?.body;
122+
// we can pull the DocuSign error code and message from the response body
123+
const errorCode = errorBody?.errorCode;
124+
const errorMessage = errorBody?.message;
125+
// In production, may want to provide customized error messages and
126+
// remediation advice to the user.
127+
res.render('pages/error', {err: error, errorCode, errorMessage});
128+
}
129+
if (results) {
130+
res.render('pages/example_done', {
131+
title: example.ExampleName,
132+
message: formatString(example.ResultsPageText, req.session.envelopeId, folderId, folderName),
133+
});
134+
}
135+
};
136+
137+
/**
138+
* Form page for this application
139+
*/
140+
eg045DeleteRestoreEnvelope.getDeleteController = (req, res) => {
141+
// Check that the authentication token is ok with a long buffer time.
142+
// If needed, now is the best time to ask the user to authenticate
143+
// since they have not yet entered any information into the form.
144+
const isTokenOK = req.dsAuth.checkToken();
145+
if (!isTokenOK) {
146+
// Save the current operation so it will be resumed after authentication
147+
req.dsAuth.setEg(req, eg);
148+
return res.redirect(mustAuthenticate);
149+
}
150+
151+
const example = getExampleByNumber(res.locals.manifest, exampleNumber, api);
152+
const sourceFile = (path.basename(__filename))[5].toLowerCase() + (path.basename(__filename)).substr(6);
153+
res.render('pages/examples/eg045DeleteEnvelope', {
154+
eg: eg, csrfToken: req.csrfToken(),
155+
example: example,
156+
envelopeId: req.session.envelopeId,
157+
submitButtonText: res.locals.manifest.SupportingTexts.HelpingTexts.SubmitButtonDeleteText,
158+
sourceFile: sourceFile,
159+
sourceUrl: dsConfig.githubExampleUrl + 'eSignature/examples/' + sourceFile,
160+
documentation: dsConfig.documentation + eg,
161+
showDoc: dsConfig.documentation
162+
});
163+
};
164+
165+
166+
/**
167+
* Form page for this application
168+
*/
169+
eg045DeleteRestoreEnvelope.getRestoreController = (req, res) => {
170+
// Check that the authentication token is ok with a long buffer time.
171+
// If needed, now is the best time to ask the user to authenticate
172+
// since they have not yet entered any information into the form.
173+
const isTokenOK = req.dsAuth.checkToken();
174+
if (!isTokenOK) {
175+
// Save the current operation so it will be resumed after authentication
176+
req.dsAuth.setEg(req, eg);
177+
return res.redirect(mustAuthenticate);
178+
}
179+
180+
if (!req.session.envelopeId) {
181+
return res.redirect(eg);
182+
}
183+
184+
const example = getExampleByNumber(res.locals.manifest, exampleNumber, api);
185+
const sourceFile = (path.basename(__filename))[5].toLowerCase() + (path.basename(__filename)).substr(6);
186+
res.render('pages/examples/eg045RestoreEnvelope', {
187+
eg: eg, csrfToken: req.csrfToken(),
188+
example: example,
189+
envelopeId: req.session.envelopeId,
190+
submitButtonText: res.locals.manifest.SupportingTexts.HelpingTexts.SubmitButtonRestoreText,
191+
sourceFile: sourceFile,
192+
sourceUrl: dsConfig.githubExampleUrl + 'eSignature/examples/' + sourceFile,
193+
documentation: dsConfig.documentation + eg,
194+
showDoc: dsConfig.documentation
195+
});
196+
};
Lines changed: 44 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,44 @@
1-
module.exports.eg001 = require('./');
2-
module.exports.eg002 = require('./eg002SigningViaEmail');
3-
module.exports.eg003 = require('./eg003ListEnvelopes');
4-
module.exports.eg004 = require('./eg004EnvelopeInfo');
5-
module.exports.eg005 = require('./eg005EnvelopeRecipients');
6-
module.exports.eg006 = require('./eg006EnvelopeDocs');
7-
module.exports.eg007 = require('./eg007EnvelopeGetDoc');
8-
module.exports.eg008 = require('./eg008CreateTemplate');
9-
module.exports.eg009 = require('./eg009UseTemplate');
10-
module.exports.eg010 = require('./eg010SendBinaryDocs');
11-
module.exports.eg011 = require('./eg011EmbeddedSending');
12-
module.exports.eg012 = require('./eg012EmbeddedConsole');
13-
module.exports.eg013 = require('./eg013AddDocToTemplate');
14-
module.exports.eg014 = require('./eg014CollectPayment');
15-
module.exports.eg015 = require('./eg015EnvelopeTabData');
16-
module.exports.eg016 = require('./eg016SetTabValues');
17-
module.exports.eg017 = require('./eg017SetTemplateTabValues');
18-
module.exports.eg018 = require('./eg018EnvelopeCustomFieldData');
19-
module.exports.eg019 = require('./eg019AccessCodeAuthentication');
20-
module.exports.eg020 = require('./eg020PhoneAuthentication');
21-
module.exports.eg022 = require('./eg022KbaAuthentication');
22-
module.exports.eg023 = require('./eg023IdvAuthentication');
23-
module.exports.eg024 = require('./eg024CreatePermission');
24-
module.exports.eg025 = require('./eg025PermissionSetUserGroup');
25-
module.exports.eg026 = require('./eg026PermissionChangeSingleSetting');
26-
module.exports.eg027 = require('./eg027DeletePermission');
27-
module.exports.eg028 = require('./eg028CreateBrand');
28-
module.exports.eg029 = require('./eg029ApplyBrandToEnvelope');
29-
module.exports.eg030 = require('./eg030ApplyBrandToTemplate');
30-
module.exports.eg031 = require('./eg031BulkSendEnvelope');
31-
module.exports.eg032 = require('./eg032PauseSignatureWorkflow');
32-
module.exports.eg033 = require('./eg033UnpauseSignatureWorkflow');
33-
module.exports.eg034 = require('./eg034UseConditionalRecipients');
34-
module.exports.eg035 = require('./eg035ScheduledSending');
35-
module.exports.eg036 = require('./eg036DelayedRouting');
36-
module.exports.eg037 = require('./eg037SmsDelivery');
37-
module.exports.eg038 = require('./eg038ResponsiveSigning');
38-
module.exports.eg039 = require('./eg039SigningInPerson');
39-
module.exports.eg040 = require('./eg040SetDocumentVisibility');
40-
module.exports.eg041 = require('./eg041CFREmbeddedSigning');
41-
module.exports.eg042 = require('./eg042DocumentGeneration');
42-
module.exports.eg043 = require('./eg043SharedAccess');
43-
module.exports.eg044 = require('./eg044FocusedView');
1+
module.exports.eg001 = require('./');
2+
module.exports.eg002 = require('./eg002SigningViaEmail');
3+
module.exports.eg003 = require('./eg003ListEnvelopes');
4+
module.exports.eg004 = require('./eg004EnvelopeInfo');
5+
module.exports.eg005 = require('./eg005EnvelopeRecipients');
6+
module.exports.eg006 = require('./eg006EnvelopeDocs');
7+
module.exports.eg007 = require('./eg007EnvelopeGetDoc');
8+
module.exports.eg008 = require('./eg008CreateTemplate');
9+
module.exports.eg009 = require('./eg009UseTemplate');
10+
module.exports.eg010 = require('./eg010SendBinaryDocs');
11+
module.exports.eg011 = require('./eg011EmbeddedSending');
12+
module.exports.eg012 = require('./eg012EmbeddedConsole');
13+
module.exports.eg013 = require('./eg013AddDocToTemplate');
14+
module.exports.eg014 = require('./eg014CollectPayment');
15+
module.exports.eg015 = require('./eg015EnvelopeTabData');
16+
module.exports.eg016 = require('./eg016SetTabValues');
17+
module.exports.eg017 = require('./eg017SetTemplateTabValues');
18+
module.exports.eg018 = require('./eg018EnvelopeCustomFieldData');
19+
module.exports.eg019 = require('./eg019AccessCodeAuthentication');
20+
module.exports.eg020 = require('./eg020PhoneAuthentication');
21+
module.exports.eg022 = require('./eg022KbaAuthentication');
22+
module.exports.eg023 = require('./eg023IdvAuthentication');
23+
module.exports.eg024 = require('./eg024CreatePermission');
24+
module.exports.eg025 = require('./eg025PermissionSetUserGroup');
25+
module.exports.eg026 = require('./eg026PermissionChangeSingleSetting');
26+
module.exports.eg027 = require('./eg027DeletePermission');
27+
module.exports.eg028 = require('./eg028CreateBrand');
28+
module.exports.eg029 = require('./eg029ApplyBrandToEnvelope');
29+
module.exports.eg030 = require('./eg030ApplyBrandToTemplate');
30+
module.exports.eg031 = require('./eg031BulkSendEnvelope');
31+
module.exports.eg032 = require('./eg032PauseSignatureWorkflow');
32+
module.exports.eg033 = require('./eg033UnpauseSignatureWorkflow');
33+
module.exports.eg034 = require('./eg034UseConditionalRecipients');
34+
module.exports.eg035 = require('./eg035ScheduledSending');
35+
module.exports.eg036 = require('./eg036DelayedRouting');
36+
module.exports.eg037 = require('./eg037SmsDelivery');
37+
module.exports.eg038 = require('./eg038ResponsiveSigning');
38+
module.exports.eg039 = require('./eg039SigningInPerson');
39+
module.exports.eg040 = require('./eg040SetDocumentVisibility');
40+
module.exports.eg041 = require('./eg041CFREmbeddedSigning');
41+
module.exports.eg042 = require('./eg042DocumentGeneration');
42+
module.exports.eg043 = require('./eg043SharedAccess');
43+
module.exports.eg044 = require('./eg044FocusedView');
44+
module.exports.eg045 = require('./eg045DeleteRestoreEnvelope');
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* @file
3+
* Example 45: Delete and Restore an Envelope
4+
* @author DocuSign
5+
*/
6+
7+
const docusign = require('docusign-esign');
8+
9+
/**
10+
* Moves the envelope to a specified folder
11+
*/
12+
const moveEnvelope = async (args) => {
13+
//ds-snippet-start:eSign45Step2
14+
const dsApiClient = new docusign.ApiClient();
15+
dsApiClient.setBasePath(args.basePath);
16+
dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken);
17+
const foldersApi = new docusign.FoldersApi(dsApiClient);
18+
//ds-snippet-end:eSign45Step2
19+
20+
//ds-snippet-start:eSign45Step3
21+
const fromFolderId = args.fromFolderId;
22+
const foldersRequest = docusign.FoldersRequest.constructFromObject({
23+
envelopeIds: [args.envelopeId],
24+
25+
// add fromFolderId parameter if its value is provided
26+
...(fromFolderId && { fromFolderId }),
27+
});
28+
//ds-snippet-end:eSign45Step3
29+
30+
//ds-snippet-start:eSign45Step4
31+
return await foldersApi.moveEnvelopes(args.accountId, args.folderId, { foldersRequest });
32+
//ds-snippet-end:eSign45Step4
33+
};
34+
35+
/**
36+
* Retrieves the list of folders
37+
*/
38+
const getFolders = async (args) => {
39+
const dsApiClient = new docusign.ApiClient();
40+
dsApiClient.setBasePath(args.basePath);
41+
dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + args.accessToken);
42+
const foldersApi = new docusign.FoldersApi(dsApiClient);
43+
44+
//ds-snippet-start:eSign45Step5
45+
return await foldersApi.list(args.accountId);
46+
//ds-snippet-end:eSign45Step5
47+
};
48+
49+
module.exports = { moveEnvelope, getFolders };

0 commit comments

Comments
 (0)