Skip to content

Commit d20091c

Browse files
author
Ruslan Tereshchenko
committed
Merge branch 'SN-3452' into SN-2955
2 parents 66e2a54 + 2696fe4 commit d20091c

File tree

6 files changed

+362
-1
lines changed

6 files changed

+362
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Added
1111

1212
- Implemented *View Template Routing Details* feature. See how to apply it in [Documentation](https://signnow.github.io/SignNowNodeSDK/class/lib/template/index.js~Template.html#static-method-getRoutingDetails), [Short example](https://github.com/signnow/SignNowNodeSDK/blob/master/README.md#routing-details), [Full example](https://github.com/signnow/SignNowNodeSDK/blob/master/samples/snippets/getRoutingDetails.js), [CLI applet](https://github.com/signnow/SignNowNodeSDK/blob/master/bin/routing-details.js).
13+
- Implemented *Update Template Routing Details* feature. See how to apply it in [Documentation](https://signnow.github.io/SignNowNodeSDK/class/lib/template/index.js~Template.html#static-method-updateRoutingDetails), [Short example](https://github.com/signnow/SignNowNodeSDK/blob/master/README.md#update-routing-details), [Full example](https://github.com/signnow/SignNowNodeSDK/blob/master/samples/snippets/updateTemplateRoutingDetails.js), [CLI applet](https://github.com/signnow/SignNowNodeSDK/blob/master/bin/update-routing-details.js).
1314

1415
### Changed
1516

README.md

+52
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ SignNow Node.js REST API Wrapper
5050
* [Create Invite to Sign a Template](#template-field-invite)
5151
* [Create Free Form Invite from Template](#template-freeform-invite)
5252
* [Remove Template](#remove-template)
53+
* [Update Routing Details](#update-routing-details)
5354
* [Folder](#folder)
5455
* [Returns a list of folders](#list-folders)
5556
* [Returns a list of documents inside a folder](#list-documents-in-folder)
@@ -602,6 +603,57 @@ api.template.getRoutingDetails({
602603

603604
More: [Full example](https://github.com/signnow/SignNowNodeSDK/blob/master/samples/snippets/getRoutingDetails.js), [CLI applet](https://github.com/signnow/SignNowNodeSDK/blob/master/bin/routing-details.js)
604605

606+
#### <a name="update-routing-details"></a>Update Routing Details
607+
608+
```javascript
609+
const routingDetails = {
610+
template_data: [
611+
{
612+
default_email: '',
613+
inviter_role: false,
614+
name: 'Signer 1',
615+
role_id: 'SIGNER 1 ROLE ID',
616+
signing_order: 1,
617+
decline_by_signature: true,
618+
},
619+
{
620+
default_email: 'signer2@mail.com',
621+
inviter_role: false,
622+
name: 'Signer 2',
623+
role_id: 'SIGNER 2 ROLE ID',
624+
signing_order: 2,
625+
},
626+
],
627+
cc: [
628+
'cc1@mail.com',
629+
'cc2@mail.com',
630+
],
631+
cc_step: [
632+
{
633+
email: 'cc1@mail.com',
634+
step: 1,
635+
name: 'CC 1',
636+
},
637+
{
638+
email: 'cc2@mail.com',
639+
step: 2,
640+
name: 'CC 2',
641+
},
642+
],
643+
invite_link_instructions: 'Invite link signing instruction',
644+
};
645+
646+
api.template.updateRoutingDetails({
647+
data: routingDetails,
648+
token: 'your auth token',
649+
id: 'template id',
650+
}, (err, res) => {
651+
// handle error or process response data
652+
});
653+
```
654+
655+
More: [Full example](https://github.com/signnow/SignNowNodeSDK/blob/master/samples/snippets/updateTemplateRoutingDetails.js), [CLI applet](https://github.com/signnow/SignNowNodeSDK/blob/master/bin/update-routing-details.js)
656+
605657
### <a name="folder"></a>Folder
606658

607659
#### <a name="list-folders"></a>Returns a list of folders

bin/update-routing-details.js

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* to run update-routing-details applet from the project root folder type in your console:
5+
* > node bin/update-routing-details <client_id> <client_secret> <username> <password> <template_id> '<routing_details>'
6+
* <client_id>, <client_secret>, <username>, <password>, <template_id>, <routing_details> - are required params
7+
*/
8+
9+
'use strict';
10+
11+
const [
12+
clientId,
13+
clientSecret,
14+
username,
15+
password,
16+
templateId,
17+
routingDetailsStringified,
18+
] = process.argv.slice(2);
19+
20+
const { promisify } = require('../utils');
21+
const api = require('../lib')({
22+
credentials: Buffer.from(`${clientId}:${clientSecret}`).toString('base64'),
23+
production: false,
24+
});
25+
26+
const {
27+
oauth2: { requestToken: getAccessToken },
28+
template: { updateRoutingDetails },
29+
} = api;
30+
31+
const getAccessToken$ = promisify(getAccessToken);
32+
const updateRoutingDetails$ = promisify(updateRoutingDetails);
33+
34+
getAccessToken$({
35+
username,
36+
password,
37+
})
38+
.then(({ access_token: token }) => {
39+
const routingDetails = JSON.parse(routingDetailsStringified);
40+
41+
return {
42+
token,
43+
routingDetails,
44+
};
45+
})
46+
.then(({ token, routingDetails }) => updateRoutingDetails$({
47+
data: routingDetails,
48+
id: templateId,
49+
token,
50+
}))
51+
.then(res => console.log(res))
52+
.catch(err => console.error(err));

lib/template/index.js

+155
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const {
1010
invite,
1111
view,
1212
} = require('../document');
13+
const { promisify } = require('../../utils');
1314

1415
/**
1516
* @type {function}
@@ -32,6 +33,52 @@ const sendDocumentInvite = invite;
3233
*/
3334
const getDocumentDetails = view;
3435

36+
/**
37+
* Update Signing Role payload
38+
* @typedef {Object} TemplateUpdateSigningRoleParams
39+
* @property {string} id - an ID of Actor (role)
40+
* @property {string} token - your auth token
41+
* @property {number} signing_order - signing order number
42+
*/
43+
44+
/**
45+
* Update Signing Role response data
46+
* @typedef {Object} TemplateUpdateSigningRoleResponse
47+
* @property {string} id - unique ID of Actor
48+
* @property {string} document_id - unique ID of Template
49+
* @property {number} signing_order - signing order number
50+
*/
51+
52+
/**
53+
* Updates Signing Role with order of actor
54+
* @param {TemplateUpdateSigningRoleParams} data - update signing role payload
55+
* @param {function(err: ApiErrorResponse, res: TemplateUpdateSigningRoleResponse)} [callback] - error first node.js callback
56+
*/
57+
const updateSigningRole = ({
58+
id,
59+
token,
60+
signing_order,
61+
}, callback) => {
62+
const JSONData = JSON.stringify({ signing_order });
63+
const req = https
64+
.request(buildRequestOptions({
65+
method: 'PUT',
66+
path: `/role/${id}`,
67+
authorization: {
68+
type: 'Bearer',
69+
token,
70+
},
71+
headers: {
72+
'Content-Type': 'application/json',
73+
'Content-Length': Buffer.byteLength(JSONData),
74+
},
75+
}), responseHandler(callback))
76+
.on('error', errorHandler(callback));
77+
78+
req.write(JSONData);
79+
req.end();
80+
};
81+
3582
/**
3683
* Template methods
3784
*/
@@ -326,6 +373,114 @@ class Template {
326373
.end();
327374
}
328375

376+
/**
377+
* Template Update Routing Details item data
378+
* @typedef {Object} TemplateUpdateRoutingDetailsItem
379+
* @property {string} default_email - default email for routing detail
380+
* @property {boolean} inviter_role - always `false`
381+
* @property {string} name - signer role (actor) name
382+
* @property {string} role_id - signer role (actor) unique ID
383+
* @property {number} signing_order - order number of signing step
384+
* @property {boolean} decline_by_signature - decline by signature flag
385+
*/
386+
387+
/**
388+
* Update Template Routing Details payload
389+
* @typedef {Object} TemplateUpdateRoutingDetailsParams
390+
* @property {TemplateUpdateRoutingDetailsItem[]} template_data - array with routing details
391+
* @property {string[]} cc - CC emails
392+
* @property {TemplateRoutingDetailsCCStep[]} cc_step - array of CC steps
393+
* @property {string} [invite_link_instructions] - invite signing instructions
394+
*/
395+
396+
/**
397+
* Update Template Routing Details response data
398+
* @typedef {Object} TemplateUpdateRoutingDetailsResponse
399+
* @property {string} id - unique ID of template routing details
400+
* @property {string} document_id - unique ID of Template
401+
* @property {TemplateUpdateRoutingDetailsItem[]} data - array with routing details
402+
* @property {string[]} cc - CC emails
403+
* @property {TemplateRoutingDetailsCCStep[]} cc_step - array of CC steps
404+
* @property {string} invite_link_instructions - invite signing instructions
405+
*/
406+
407+
/**
408+
* Updates Routing Details of specified template
409+
* @param {TemplateUpdateRoutingDetailsParams} data - update Template Routing Details payload
410+
* @param {function(err: ApiErrorResponse, res: TemplateUpdateRoutingDetailsResponse)} [callback] - error first node.js callback
411+
*/
412+
static updateRoutingDetails ({
413+
id,
414+
token,
415+
data,
416+
}, callback) {
417+
const {
418+
template_data,
419+
cc,
420+
cc_step,
421+
invite_link_instructions,
422+
} = data;
423+
const JSONData = JSON.stringify({
424+
template_data,
425+
cc,
426+
cc_step,
427+
invite_link_instructions,
428+
});
429+
430+
const updateCallback = (err, res) => {
431+
if (err) {
432+
callback(err);
433+
return;
434+
} else {
435+
const { data: routingDetails } = res;
436+
const rolesUpdated = routingDetails
437+
.map(route => {
438+
const { role_id, signing_order } = route;
439+
return promisify(updateSigningRole)({
440+
id: role_id,
441+
signing_order,
442+
token,
443+
});
444+
});
445+
446+
Promise.all(rolesUpdated)
447+
.then(roleUpdatesRes => {
448+
return roleUpdatesRes.reduce((generalStatus, roleUpdateRes) => (generalStatus && !!roleUpdateRes.id), true);
449+
})
450+
.then(allRolesUpdated => {
451+
if (allRolesUpdated) {
452+
callback(null, res);
453+
return;
454+
} else {
455+
throw new Error('Some roles (actors) where not updated');
456+
}
457+
})
458+
.catch(roleUpdatesErr => {
459+
callback(roleUpdatesErr);
460+
return;
461+
});
462+
}
463+
};
464+
465+
const req = https
466+
.request(buildRequestOptions({
467+
method: 'PUT',
468+
path: `/document/${id}/template/routing/detail`,
469+
authorization: {
470+
type: 'Bearer',
471+
token,
472+
},
473+
headers: {
474+
'Content-Type': 'application/json',
475+
'Content-Length': Buffer.byteLength(JSONData),
476+
},
477+
}), responseHandler(updateCallback))
478+
.on('error', errorHandler(callback));
479+
480+
req.write(JSONData);
481+
req.end();
482+
}
483+
329484
}
330485

331486
module.exports = Template;

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@
7676
"sn:view-document-group": "./bin/view-document-group.js",
7777
"sn:view-document": "./bin/view-document.js",
7878
"sn:view-documentgroup-template": "./bin/view-documentgroup-template.js",
79-
"sn:routing-details": "./bin/routing-details.js"
79+
"sn:routing-details": "./bin/routing-details.js",
80+
"sn:update-routing-details": "./bin/update-routing-details.js"
8081
},
8182
"license": "MIT"
8283
}

0 commit comments

Comments
 (0)