Docusign API - request for signature using Template - docusignapi

I am trying to test the REST API for request a signature on a document referenced through a template using C# in a WCF webservice.
The Step 1 for Login works & returns the accountID & baseURl;
The Step 2 fails with a Bad Request.
Here is my code:
try {
...
string requestBody = "<envelopeDefinition xmlns=\"http://www.docusign.com/restapi\">" +
"<accountId>" + accountId + "</accountId>" +
"<status>" + "sent" + "</status>" +
"<emailSubject>" + "API Call for Embedded Sending" + "</emailSubject>" +
"<emailBlurb>" + "This comes from C#" + "</emailBlurb>" +
"<templateId>" + "9A535489-0FB6-42B2-82C1-A06DA36025B4" + "</templateId>" +
"<templateRoles>" +
"<email>" + "abc#gmail.com" + "</email>" + // NOTE: Use different email address if username provided in non-email format!
"<name>" + "GRAVITY1003" + "</name>" + // username can be in email format or an actual ID string
"<roleName>" + "GRAVITY1003" + "</roleName>" +
"</templateRoles>" +
"</envelopeDefinition>";
// append "/envelopes" to baseUrl and use in the request
request = (HttpWebRequest)WebRequest.Create(baseURL + "/envelopes");
request.Headers.Add("X-DocuSign-Authentication", authenticateStr);
request.ContentType = "application/xml";
request.Accept = "application/xml";
request.ContentLength = requestBody.Length;
request.Method = "POST";
// write the body of the request
byte[] body = System.Text.Encoding.UTF8.GetBytes(requestBody);
Stream dataStream = request.GetRequestStream();
dataStream.Write(body, 0, requestBody.Length);
dataStream.Close();
// read the response
webResponse = (HttpWebResponse)request.GetResponse();------> It fails here
sr = new StreamReader(webResponse.GetResponseStream());
responseText = sr.ReadToEnd();
uri = responseText;
}
catch (WebException e)
{
using (WebResponse response = e.Response)
{
HttpWebResponse httpResponse = (HttpWebResponse)response;
Console.WriteLine("Error code: {0}", httpResponse.StatusCode);
using (Stream data = response.GetResponseStream())
{
string text = new StreamReader(data).ReadToEnd();
Console.WriteLine(text);
}
}
}
Can anyone tell me what I am doing wrong ? I looked at the API walkthrough's & coded this accordingly. Not sure why this is happening.

Looks like there was a bug in the Gist you were working off of, the wrong version was mistakenly uploaded. The Gist has been fixed, the issue was just one xml node that was missing.
Since you can have multiple template roles on a given template, there needs to be an extra xml node that separates each role. What you need to do is add singular <templateRole></templateRole> xml nodes in between the <templateRoles></templateRoles> nodes.
So your request body should look like this:
<?xml version="1.0" encoding="UTF-8"?>
<envelopeDefinition xmlns="http://www.docusign.com/restapi">
<accountId>123456</accountId>
<status>sent</status>
<emailSubject>API Call for sending signature request from template</emailSubject>
<emailBlurb>This comes from Java</emailBlurb>
<templateId>EA64D446-3BFA-*********************</templateId>
<templateRoles>
<templateRole>
<email>recipient_email_address</email>
<name>recipient_name</name>
<roleName>template_role_name</roleName>
</templateRole>
</templateRoles>
</envelopeDefinition>

Related

Azure Table Storage (Table Services REST API) SharedKeyLite not working

After seeing through this link, I tried the same in my postman.
var storageAccount = "mystorage";
var accountKey = "<<primaryKey>>";
var date = new Date();
var UTCstring = date.toUTCString();
var data = UTCstring + "\n" + "/mystorage/Health"
var encodedData = unescape(encodeURIComponent(data));
var hash = CryptoJS.HmacSHA256(encodedData, CryptoJS.enc.Base64.parse(accountKey));
var signature = hash.toString(CryptoJS.enc.Base64);
var auth = "SharedKeyLite " + storageAccount + ":" + signature;
postman.setEnvironmentVariable("auth", auth);
postman.setEnvironmentVariable("date", UTCstring);
When I make the request to ATS, to the following url,
I get the auth denied!
Can someone please guide me what's going wrong here?!
I think you need to generate a bearer token and put it to the Authorization of Postman.
If you are using C#, you can use this to get the bearer token:
AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
string accesstoken = azureServiceTokenProvider.GetAccessTokenAsync("https://storage.azure.com/").Result;
string bearertoken = "Bearer " + accesstoken;
Then Copy the bearer token:
After that, it should be ok.
Just realized that the url and the data that we are encoding should exactly match the url we are querying...
After changing
var data = UTCstring + "\n" + "/mystorage/Health"
to
var data = UTCstring + "\n" + "/mystorage/Health(PartitionKey='USA',RowKey='WA')"
things started working.
Update :
It just expects the right table query. The following works fine,
var data = UTCstring + "\n" + "/mystorage/Health()"
with all filter expressions in the url being invoked from postman.

sharepoint - starting workflow jsom script works on premise but fails online?

I have a piece of javascript code starting a workflow.
It all works on my on premise dev machine.
But as soon as I try to run it on an online site, it fails.
It is based on the workflow.asmx web service, and I get error 500 - value does not fall on expected range...
I suspect this is in the workflow parameters. But I cannot see what exactly. The user login differs but it is compliant with oneline format...
Any idea about any possible differences between on premise vs online that might explain this?
just in case, here's my code (again, perfectly fine onpremise):
function StartMyWorkflow(listGUID, itemId) {
var wfDefinitionId = "{9279E1FF-1D32-4423-85B7-C7F21998A701}";
var ctx = SP.ClientContext.get_current();
var web = ctx.get_web();
var list = web.get_lists().getById(listGUID);
var item = list.getItemById(itemId);
var currentUser = web.get_currentUser();
ctx.load(web);
ctx.load(item);
ctx.load(currentUser);
ctx.executeQueryAsync(
Function.createDelegate(this, function () {
var login = currentUser.get_loginName();
var name = currentUser.get_title();
var xml = getWFAssocData(name, login);
var fileRef = "https://" + location.host + item.get_item("FileRef");
$().SPServices({
operation: "StartWorkflow",
item: fileRef,
templateId: wfDefinitionId,
workflowParameters: xml,
completefunc: function () {
SP.UI.Notify.addNotification('workflow started', false);
}
});
}),
function (s, a) { console.error(a.get_message());}
);
}
function getWFAssocData(name, login) {
var assocData = '<dfs:myFields xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:dms="http://schemas.microsoft.com/office/2009/documentManagement/types" xmlns:dfs="http://schemas.microsoft.com/office/infopath/2003/dataFormSolution" xmlns:q="http://schemas.microsoft.com/office/infopath/2009/WSSList/queryFields" xmlns:d="http://schemas.microsoft.com/office/infopath/2009/WSSList/dataFields" xmlns:ma="http://schemas.microsoft.com/office/2009/metadata/properties/metaAttributes" xmlns:pc="http://schemas.microsoft.com/office/infopath/2007/PartnerControls" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' +
'<dfs:queryFields></dfs:queryFields>' +
'<dfs:dataFields>' +
'<d:SharePointListItem_RW>' +
'<d:Approvers>' +
'<d:Assignment>' +
'<d:Assignee>' +
'<pc:Person><pc:DisplayName>' + name + '</pc:DisplayName><pc:AccountId>' + login + '</pc:AccountId><pc:AccountType>User</pc:AccountType></pc:Person>' +
'</d:Assignee>' +
'<d:Stage xsi:nil="true" />' +
'<d:AssignmentType>Serial</d:AssignmentType>' +
'</d:Assignment>' +
'</d:Approvers>' +
'<d:ExpandGroups>true</d:ExpandGroups>' +
'<d:NotificationMessage>Please approve test</d:NotificationMessage>' +
'<d:DueDateforAllTasks xsi:nil="true" /><d:DurationforSerialTasks xsi:nil="true" />' +
'<d:DurationUnits>Day</d:DurationUnits>' +
'<d:CC />' +
'<d:CancelonRejection>true</d:CancelonRejection>' +
'<d:CancelonChange>false</d:CancelonChange>' +
'<d:EnableContentApproval>false</d:EnableContentApproval>' +
'</d:SharePointListItem_RW>' +
'</dfs:dataFields>' +
'</dfs:myFields>';
return assocData;
}
It turns out to be as silly as obvious. I was just missing a 's' in the fileRef url... I've corrected the above script, so it's actually fully functional.

oAuth2 web request works in browser but not in app

I have the following code sample with which I'm trying to authenticate an Azure active directory user within a Xamarin forms app
The URL (I've removed the actual client ID) works fine in a browser but fails when trying to send the http request
The error message says 'the response type must include client_id'
string URL = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?"
+ "client_id=xxxx-xxxxx-xxxxx-xxxxx-xxx"
+ "&response_type=code"
+ "&redirect_uri=https://login.microsoftonline.com/common/oauth2/nativeclient"
+ "&response_mode=query"
+ "&scope=openid%20offline_access%20https%3A%2F%2Fgraph.microsoft.com%2Fmail.read"
+ "&state=12345";
var webRequest = System.Net.WebRequest.Create(URL) as HttpWebRequest;
System.Console.WriteLine(URL);
if (webRequest != null)
{
webRequest.Method = "POST";
webRequest.ServicePoint.Expect100Continue = false;
webRequest.Timeout = 20000;
webRequest.ContentType = "text/html";
//POST the data.
using (requestWriter = new StreamWriter(webRequest.GetRequestStream()))
{
requestWriter.Write(postData);
}
}
HttpWebResponse resp = (HttpWebResponse)webRequest.GetResponse();
Stream resStream = resp.GetResponseStream();
StreamReader reader = new StreamReader(resStream);
ret = reader.ReadToEnd();
You put parameters in the URL, so you need to use GET method, instead of POST (like your browser does when you paste the URL in its address bar).
So, replace:
webRequest.Method = "POST";
by:
webRequest.Method = "GET";
and remove:
//POST the data.
using (requestWriter = new StreamWriter(webRequest.GetRequestStream()))
{
requestWriter.Write(postData);
}

how to void an envelope using C# / XML?

Can anyone tell me how to fix this code, I just get an 400 error:
public string VoidEnvelope(string envelopeID)
{
string url = baseURL + "/envelopes/" + envelopeID;
string requestBody =
"<envelopeDefinition xmlns=\"http://www.docusign.com/restapi\">" +
"<status>voided</status>" +
"<voidedReason>user aborted</voidedReason>" +
"</envelopeDefinition>";
HttpWebRequest request = initializeRequest(url, "PUT", requestBody, email, password);
string response = getResponseBody(request);
return response;
}
When creating an envelope by doing a POST to the /envelopes URI the outer most XML element is defined as
<envelopeDefinition ...
However when modifying an existing envelope using a PUT, the outer most XML element is defined simply as
<envelope ...
So try something like this:
"<envelope>" +
"<status>voided</status>" +
"<voidedReason>user aborted</voidedReason>" +
"</envelope>";
A great resource that many people (including myself) forget about is the Rest API help page. That is probably your best way of learning the XML request bodies and all the potential nodes (it's also great for JSON!)
https://www.docusign.net/restapi/help

How to get the favorites from flickr

I am working on Node.js to get the list of favorites photos from a user in flickr, I know there is other method to get the public list of favorites, and that one works fine to me, but using this the flickr API return me this error.
{"stat":"fail", "code":98, "message":"Invalid auth token"}
This is my code:
var util = require('util'),
http = require('http'),
keys = require(__dirname + '/../oauth/flickrKeys'),
utilities = require(__dirname + '/Utilities');
var getPhotos = function(userInfo, callback) {
var requestResponse,
parameters,
requestPoint,
url,
toHash,
secretKey,
api_signature,
method = "flickr.favorites.getList",
format = "json";
requestPoint = 'http://api.flickr.com/services/rest/';
url = requestPoint
+ '?api_key=' + keys.clave
+ '&auth_token=' + userInfo.oauth_token
+ '&format=' + format
+ '&method=' + method
+ '&min_fave_date=' + userInfo.min_fave_date
+ '&nojsoncallback=1'
+ '&user_id=' + encodeURIComponent(userInfo.user_nsid);
parameters = 'api_key=' + keys.clave
+ '&auth_token=' + userInfo.oauth_token
+ '&format=' + format
+ '&method=' + method
+ '&min_fave_date=' + userInfo.min_fave_date
+ '&nojsoncallback=1'
+ '&user_id=' + encodeURIComponent(userInfo.user_nsid);
toHash = 'GET&'
+ encodeURIComponent(requestPoint) + '&'
+ encodeURIComponent(parameters);
// coding hash.
secretKey = keys.secreto + "&" + userInfo.oauth_token_secret;
api_signature = utilities.generateFlickrSignatureHex(toHash, secretKey);
// adding api signature to the url.
url = url + '&api_sig=' + encodeURIComponent(api_signature);
http.get(url, function(res) {});
}
at the below line
url = requestPoint
+ '?api_key=' + keys.clave
+ '&auth_token=' + userInfo.oauth_token
+ '&format=' + format
+ '&method=' + method
+ '&min_fave_date=' + userInfo.min_fave_date
+ '&nojsoncallback=1'
+ '&user_id=' + encodeURIComponent(userInfo.user_nsid);
i think you haven't initialized userInfo object before this, which causes the mentioned authentication error related to userInfo.oauth_token
updated to question edit
make sure userInfo has a oauth_token attribute before calling the api.just like you can wrap the api call inside a check like
if(typeof(userInfo)!="undefined" && typeof(userInfo.oauth_token)!="undefined" && userInfo.oauth_token!="") {
//code for api call
}

Resources