Technical Articles
Electronic Contract Signing: Docusign Integration with SuccessFactors EC – Part 2
Hello Everyone,
This is the Part 2 of the blog “Electronic Contract Signing: Docusign Integration with SuccessFactors”. In this Part 2 we will focus on rest of step and final demo.
Step 4: Create oData service using CDS model and Cloud Platform Backend Service.
We need some storage which will store the data of all users who already got the contract so that if again some one try to trigger some change from SFEC Integration Center it will not send contract again and easiest way to do this is using SAP Cloud Platform Cloud Foundry Backend Service. Using CDS model we will create the oDATA service in the fly which will be used for storing user data and checking that user has already contract or not.
If you are very new to SAP Cloud Platform Backend Service, Please have a look at this series of tutorial.
In order to use the SAP Cloud Platform Backend Service, First we need to subscribe the Backend Service in Subscription.
Now Create the CDS Model File (docusign.cds), remember file extension should be .cds
service docusign {
entity user {
key userID : String;
sent: Boolean;
}
}
Click on Create API
Upload the cds file and fill the all information and click on create API button to create the oData service.
Initially it will be in pending status then it ll be changed to Active.
Click on this API and explore the swagger API. If you want to use V2 oData you can check V2 also.
.
Step 5: Create XSUAA instance for Calling Backend Service API from Node.Js Application.
We can’t directly call Backend service API from outside , for that we need to create XSUAA Instance
and configure the XSUAA with Backend Service.
In order to configure XSUAA for Backend Service follow this great blog.
In order to see how you can test Backend service API from outside in tools like Postman follow this
Step 6: Developing and Deploying Node.Js Application in Cloud Foundry which will handle the logic for sending Contract to Employee.
const express = require('express')
const bodyParser = require('body-parser')
const oauthClient = require('client-oauth2')
const request = require('request-promise')
const app = express()
const port = process.env.PORT || 3000
app.use(bodyParser.json())
app.post('/sendmail', (req, res) => {
const email = req.body.email;
const userid = req.body.userid;
const fname = req.body.fname;
const lname = req.body.lname;
const full_name = fname + " " + lname;
const contractCheck = function(email, userid, full_name, accessToken) {
const userid1 = "'" + userid + "'";
const serviceUrl = "https://backend-service-api.cfapps.eu10.hana.ondemand.com/odatav2/DEFAULT/DOCUSIGN;v=1/user(" + userid1 + ")";
return new Promise(function(resolve, reject) {
const options = {
url: serviceUrl,
resolveWithFullResponse: true,
headers: {
Authorization: 'Bearer ' + accessToken,
Accept: 'application/json'
}
};
request(options)
.then(response => {
if (response && response.statusCode == 200) {
resolve(res.send('contract has been already sent'));
}
})
.catch(error => {
resolve(sendContract(email, full_name, userid, accessToken));
});
});
}
const gettingToken = function() {
return new Promise((resolve, reject) => {
const oautClient = new oauthClient({
accessTokenUri: 'https://<your_sub_account>.authentication.eu10.hana.ondemand.com/oauth/token',
clientId: '<xsuaa client id>',
clientSecret: '<xsuaa client secret>',
scopes: []
});
oautClient.owner.getToken('<your scp email>', '<your scp password>')
.then(result => {
resolve({
accessToken: result.accessToken
});
})
.catch(error => {
reject({
message: 'Error: failed to get access token.',
error: error
});
});
});
}
const sendContract = function(email, full_name, userid, accessToken) {
var url = 'https://api.openconnectors.ext.hanatrial.ondemand.com/elements/api-v2/envelopes';
var headers = {
'authorization': 'User IXnG2ZC2lpg34sd6e2sNWCXTO098272XMAqldM=, Organization 927730555109ef5261b78359b8761, Element gg8vdijY0R0O7y0sBx09yK49mDCbhFzeMWiW/XJM50=',
'accept': 'application/json',
'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
};
bodyJson = {
"compositeTemplates": [{
"compositeTemplateId": "1",
"inlineTemplates": [{
"recipients": {
"carbonCopies": [{
"email": "<email id of where you want copy>",
"name": "Sudip Ghosh",
"recipientId": "2"
}],
"signers": [{
"email": email,
"name": full_name,
"recipientId": "1",
"roleName": "Employee",
"tabs": {
"textTabs": []
}
}]
},
"sequence": "1"
}],
"serverTemplates": [{
"sequence": "2",
"templateId": "c7d72cca-3391-45d3-aee0-40d6558b037a"
}]
}],
"emailSubject": "Employment Training Bond",
"enableWetSign": "false",
"status": "sent"
}
var options = {
method: 'POST',
url: url,
headers: headers,
formData: {
envelope: JSON.stringify(bodyJson)
}
};
request(options, function(error, response, body) {
if (!error && response.statusCode == 200) {
const backendAPIurl = 'https://backend-service-api.cfapps.eu10.hana.ondemand.com/odatav2/DEFAULT/DOCUSIGN;v=1/user';
bodyData = {
"userID": userid,
"sent": true
}
var options = {
'method': 'POST',
'url': backendAPIurl,
'headers': {
'Authorization': 'Bearer ' + accessToken,
'Content-Type': 'application/json'
},
body: JSON.stringify(bodyData)
};
request(options, function(error, response) {
if (!error && response.statusCode == 201) {
res.send('Contract has been sent');
} else {
res.send('Error Happened');
}
if (error) throw new Error(error);
console.log(response.body);
});
} else {
res.send('Error happened')
}
})
}
gettingToken()
.then(result => {
console.log('Successfully fetched OAuth access token: ' + result.accessToken.substring(0, 16));
return contractCheck(email, userid, full_name, result.accessToken);
})
.catch(error => {
console.log(error.message + ' Reason: ' + error.error);
res.send(error.message + ' Reason: ' + error.error);
});
})
app.listen(port, () => {
console.log('Server is running on port ' + port)
})
On successful deployment you will be able to see the application running on SAP Cloud Platform Cloud Foundry like below
Step 7: Configure a Destination in Integration Center, which will call the node.js application and pass the recent change employee Data.
Login to SuccessFactors Employee Central and navigate to Integration center
Click on My Integration then create – > More Integration Types
Select Destination Type Rest, source type SuccessFactors
Give meaningful Integration name and Description in my case i have given Docusign
Choose user entity and select the fields you want to pass
Select the filter, in my cases i have selected time-based filter
Now this is the main part, configure the rest API URL, Select Method type POST
Below is the final configuration how it looks like.
Now we have done all the technical configuration required, Now it’s time to test this whole scenario.
Step 8: Testing the whole scenario (Demo)
I hope everyone will like this Blog, If you like this blog, Please don’t forget to like, comment and share. Again Happy new year, i wish this year brings lots of opportunity to everyone and make SAP Community more great.
Useful
Hello Chippy,
Thank you so much :-). I am glad you found it useful.
Regards,
Sudip
Hi Sudip Ghosh,
Thanks for sharing the information.
Can you please confirm do we need separate licence for Docusign Sand Box Account?
Because I can see while doing registration its dummy account and will get expire soon.
Thanks.
Best Regards,
Sushil Maurya
Hello Sushil,
I am not sure for sandbox, there shouldn't be any such. For me its working for last 1 month. But definitely you need license to use productive version.
Regards,
Sudip
Hi Sudip,
Very interesting article and thank you for this information. I had few questions with regards to the approach mentioned below :
Thanks and Regards,
Rithin Thomas
Yes you can definately do that, thats what is happening here. I am pulling the email id of employee from SF. and yes for more than one data template you need to create multiple interfaces
Hi Sudip,
How do we do for Adobe sign instead docusign?
Thanks
Venkatesh
Hello Venkatesh,
I see open connector also available for Adobe sign you can use the API in same way i have used here for docusign.
Regards,
Sudip
Hi Sundip Gosh,
Thank you for the Blog, Implementing similar steps but unable to deploy the node.js app (Step :6) in Cloud Foundry as facing issue in quota memory plan. Below is the screen shot of the error. Please let me know how can I proceed further.
Thanks & Regards,
Sheba.
you are running out of quota in your cf account, pleaase stop/delete some route.
Thanks Sudip Ghosh , now able to deploy the application. when I trigger in integration centre it is running successfully. Since it is not connecting DocuSign through Node.js application when executed the logs we found these error.
Thanks.
Hi Sudip Ghosh,
I've finshed all the steps, but when i go to the link a have this error
Hi Sudip,
We are trying to integrate Employee Central with DocuSign, but the plugin is not available.
I read your post Part1 and Part 2. I have 2 questions
In Part 2, you have brought all node.js and everything , is it required?
How have you done the mapping of the fields placed in DocuSign document?
Regards
Which plugin? You can use any other middleware instead of node js
Hello Sudip,
Thanks for the great article. Very informative and useful.
In your demo video, I noticed that the name of the candidate is pre-populated in the letter. Did you setup that field mapping? If so, could you please let me know where have you specified that mapping?
Also, can we setup the mapping between any SF field and fields on the document?
Regards,