DocuSign - View Form Data - docusignapi

Another company we partner with sends us new client information via DocuSign envelopes completed by those clients. I am attempting to extract the form data from the document, either via the PDF or via the DocuSign API. The PDF only appears to have the Envelope ID embedded in it. When I add my account as a CC recipient and try to view the form data in the DocuSign console, I receive an error message:
Additionally, I'm unable to view the form data via the DocuSign API.
{
errorCode: "USER_LACKS_PERMISSIONS",
message: "This user lacks sufficient permissions to access this resource."
}
I've tried accessing via the API at:
/v2/accounts/{accountId}/envelopes/{envelopeId}/recipients/{recipientId}/tabs
/v2/accounts/{accountId}/envelopes/{envelopeId}/documents/{documentId}/fields
Questions:
Is there a way for a user who is not in the sender's tenant to be able to view the envelope form data?
Is there a way for DocuSign to embed the tab data into the PDF for extraction?
Is there another approach I'm not considering?

If the user is cc to the envelope using the same userId and email combination that is on their account, then that user also can use the API to gain account information. (account is what you call "tenant.")
If the user is not on the envelope and you just receive the PDF some other way, then you cannot use the API to obtain information about the envelope because that is limited only to recipients of the envelope.

#Inbar-Gazit was kind enough to do some digging internally at DocuSign, and after a bit of back-and-forth, discovered that this is possible using the SOAP API with the RequestEnvelope and RequestEnvelopeV2 methods. I'm unsure if there's any advantage to using one method over the other. Both also have async methods.
https://developers.docusign.com/docs/esign-soap-api/reference/Status-and-Managing-Group/RequestEnvelope
Some quick-and-dirty C# validated that this will indeed work. I validated this both as the sending account (which also works via REST) and the CC recipient account (which did not work via REST).
var authString = $"<DocuSignCredentials><Username>{_userName}</Username><Password>{_password}</Password><IntegratorKey>{_apiKey}</IntegratorKey></DocuSignCredentials>";
var client = new DSAPIServiceSoapClient();
using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
{
HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers.Add("X-DocuSign-Authentication", authString);
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
EnvelopeStatus status = client.RequestStatusEx(_envelopeId);
Console.Out.WriteLine("Subject: " + status.Subject);
// RequestEnvelope Method
var envelope = client.RequestEnvelope(_envelopeId, false);
var testTab = envelope.Tabs.FirstOrDefault(t => t.TabLabel.Contains("Test"));
if (testTab != null)
{
Console.WriteLine($"Tab {testTab.TabLabel}: {testTab.Value}");
} else
{
Console.WriteLine("Tab not found.");
}
// RequestEnvelopeV2 Method
var requestOptions = new RequestEnvelopeV2Options() {
IncludeAC = false,
IncludeAnchorTabLocations = true,
IncludeDocumentBytes = false
};
var envelopeV2 = client.RequestEnvelopeV2(_envelopeId, requestOptions);
var testTabV2 = envelopeV2.Tabs.FirstOrDefault(t => t.TabLabel.Contains("Test"));
if (testTabV2 != null)
{
Console.WriteLine($"Tab(v2) {testTabV2.TabLabel}: {testTabV2.Value}");
} else
{
Console.WriteLine("Tab(v2) not found.");
}
Console.WriteLine("\r\nDone.");
Console.ReadKey();
}
Output:
Subject: Please DocuSign: Test Envelope
Tab txtDataLabelTest1: Some Data Here
Tab(v2) txtDataLabelTest1: Some Data Here
Done.

Related

event notification of envelope in DocuSign restapi c#,webapi

I have added event notification at the time of envelope creation in EnvelopeCreate Method as
apiClient.Configuration.DefaultHeader.Add("Authorization", "Bearer " + AccessToken);
EnvelopesApi envelopesApi = new EnvelopesApi(apiClient);
EnvelopeSummary results = envelopesApi.CreateEnvelope(AccountId, env);
EventNotificationForEnvelope();
and EventNotificationForEnvelope method is as
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
EnvelopeDefinition envelopeDefinition = new EnvelopeDefinition();
var eventNotification = new EventNotification();
// Set up the endpoint URL to call (it must be using HTTPS and at least TLS1.1 or higher)
eventNotification.Url = "https:\\testapi.example.com/api/DocuSignEventNotification";
// DocuSign will retry on failure if this is set
eventNotification.RequireAcknowledgment = "true";
// This would send the documents together with the event to the endpoint
eventNotification.IncludeDocuments = "true";
// Allows you to see this in the DocuSign Admin Connect logs section
eventNotification.LoggingEnabled = "true";
var envelopeEvents = new List<EnvelopeEvent>();
// In this case we only add a single envelope event, when the envelope is completed. You can also add events for recipients
envelopeEvents.Add(new EnvelopeEvent { EnvelopeEventStatusCode = "completed",
IncludeDocuments = "true" });
eventNotification.EnvelopeEvents = envelopeEvents;
envelopeDefinition.EventNotification = eventNotification;
and in my api's controller as
public class DocuSignEventNotificationController : ApiController
{
[HttpPost]
[HttpGet]
public HttpResponseMessage DocuSignDocumentStatus(HttpResponseMessage responseMessage)
{
dynamic response = responseMessage.Content.ReadAsStringAsync();
//here I will read values from response and use in my application
return Request.CreateResponse(HttpStatusCode.OK, "Testing");
}
}
I am not getting any response on envelope create and when status is updating of that envelope
A couple of things.
First,
https:\testapi.example.com/api/DocuSignEventNotification
Is not where you have your server I presume. Make sure that you use https and that your server is configured correctly to accepts TLS (1.2 and above).
Using a cloud service or some other third-party instead of building your own is much easier. If you do use your own, you may need to ensure firewall etc. allow for requests coming from the internet.
Second,
There's a log that you can find in the Connect section settings area in the DocuSign web app that can show you all attempts to reach servers. That can help you figure out if the request was made correctly to DocuSign and if DocuSign attempted to call your server and if so - what error may have been returned.
Just click "Logs":

Error calling CreateRecepientView: Unknown_envelope_Recipient

Would like to generate a DocuSign Url to embed to a web application.
Got below print screen. Questions
1 Where to get the "SignerCliendId"(the 3rd parameter of MakeRecipientViewRequest)?
2 How to handle "Unknown_envelope_Recipient"?
BugPrintScreen
Thanks
I set the clientUserId = '1000', in MakeEnvelope() using the below code.
Signer1.ClientUserId = "1000"
and used RecipientViewRequest
viewRequest = MakeRecipientViewRequest(signerEmail, signerName, "1000");
Then, it works!
I cannot see your MakeRecipientViewRequest() method, but look below I provide
the C# code that does what you need. The issue here is that you must match the recipient (singer) information for which you are generating a signer view. The system wasn't able to find such a recipient and that's why you got the error.
(I also noticed you use a template, so may need to check how that was done too)
RecipientViewRequest viewRequest = MakeRecipientViewRequest(signerEmail, signerName);
private RecipientViewRequest MakeRecipientViewRequest(string signerEmail, string signerName)
{
// Data for this method
// signerEmail
// signerName
// dsPingUrl -- class global
// signerClientId -- class global
// dsReturnUrl -- class global
RecipientViewRequest viewRequest = new RecipientViewRequest();
// Set the url where you want the recipient to go once they are done signing
// should typically be a callback route somewhere in your app.
// The query parameter is included as an example of how
// to save/recover state information during the redirect to
// the DocuSign signing ceremony. It's usually better to use
// the session mechanism of your web framework. Query parameters
// can be changed/spoofed very easily.
viewRequest.ReturnUrl = dsReturnUrl + "?state=123";
// How has your app authenticated the user? In addition to your app's
// authentication, you can include authenticate steps from DocuSign.
// Eg, SMS authentication
viewRequest.AuthenticationMethod = "none";
// Recipient information must match embedded recipient info
// we used to create the envelope.
viewRequest.Email = signerEmail;
viewRequest.UserName = signerName;
viewRequest.ClientUserId = signerClientId;
// DocuSign recommends that you redirect to DocuSign for the
// Signing Ceremony. There are multiple ways to save state.
// To maintain your application's session, use the pingUrl
// parameter. It causes the DocuSign Signing Ceremony web page
// (not the DocuSign server) to send pings via AJAX to your
// app,
viewRequest.PingFrequency = "600"; // seconds
// NOTE: The pings will only be sent if the pingUrl is an https address
viewRequest.PingUrl = dsPingUrl; // optional setting
return viewRequest;
}

Create DocuSign user without sending activation email using eSign SDK?

I am using DocuSign eSign SDK V3.1.1 to create user in DocuSign without sending any activation email to user. I want password and forgotten password information to be set from API itself so that after this call user can immediately start using their account. I am using below code for this purpose:
UserInformation userInformation = new UserInformation()
{
UserName = data["UserName"],
Email = data["UserEmail"],
SendActivationEmail = "false",
Password = "123456",
ForgottenPasswordInfo = new ForgottenPasswordInformation()
{
ForgottenPasswordQuestion1 = "What is the name of your first pet?",
ForgottenPasswordAnswer1 = "Pogo"
},
PermissionProfileId = "XXXXX"
};
List<UserInformation> usersInfo = new List<UserInformation>() { userInformation };
NewUsersDefinition newUsersDefinition = new NewUsersDefinition()
{
NewUsers = usersInfo
};
var result = usersApi.Create(accountId, newUsersDefinition);
However, the ctivation email is still sent to user and password and forgotten password is not set from the API. Am I missing something in above request? Or do I need to set any other parameter to achieve the requirement?
Silent Activation through the eSignature API is only available on some account types, and is no longer generally available. The supported way to do this is now through the Organization API, as documented here: https://developers.docusign.com/orgadmin-api/code-examples/add-user
If you don't currently have an Organization with a Claimed Domain, you'll want to reach out to your Account Manager or the Sales team to have the Organization module added to your account. DocuSign Support can enable that on a Demo/Sandbox account, open a Support case and provide your demo account ID.

USER_AUTHENTICATION_FAILED Creating Envelope

Currently I'm working with a Node.js integration for DocuSign (https://www.npmjs.com/package/docusign-esign), I made all the test with the sandbox account and worked perfectly, right now I'm trying to use a production account, the login process is fine but when I'm going to create the envelope I get a USER_AUTHENTICATION_FAILED error (even if the first login went without errors). I would like to know if someone has experienced same thing or has an idea of how can I fix this.
This is the code that I took from the docusign-esign to create the envelope:
var loginAccount = new docusign.LoginAccount();
loginAccount = loginAccounts[0];
var accountId = loginAccount.accountId;
var envelopesApi = new docusign.EnvelopesApi();
envelopesApi.createEnvelope(accountId, envDef, null, function (error, envelopeSummary, response)
The account Id is the same retrieved after the login process.
One possible cause could be that your DocuSign account is hosted on na2.docusign.net, na3.docusign.net or eu.docusign.net, while your code uses the default www.docusign.com as a base URL.
The login call will pass even if you use www, however all the subsequent API calls will fail if you are not hitting the exact base URL that corresponds to your production account. You should have received this information as part of the DocuSign Go-Live process (formerly known as API Certification). You can always get the base URL from the login call response.
For Node, here how to get the correct base URL from the login call and set it up to the API Client (lines in bold are likely what is missing in your code):
authApi.login(loginOps, function (err, loginInfo, response) {
if (err) {
return next(err);
}
if (loginInfo) {
// list of user account(s)
// note that a given user may be a member of multiple accounts
var loginAccounts = loginInfo.getLoginAccounts();
console.log('LoginInformation: ' + JSON.stringify(loginAccounts));
var loginAccount = loginAccounts[0];
var accountId = loginAccount.accountId;
var baseUrl = loginAccount.baseUrl;
var accountDomain = baseUrl.split("/v2");
apiClient.setBasePath(accountDomain[0]);
docusign.Configuration.default.setDefaultApiClient(apiClient);
next(null, loginAccount);
}
});

Use the Outlook/Office365 REST API to send mail from connected email address

I am trying to send an email using the Outlook/Office 365 REST API, and I am trying to send it as an address that I have as a "Connected Account". Attempting to send the message returns a `` error. However, the API will let me create a draft with this address.
Additionally, I can send the API-created draft just fine, and I can also create and send messages as this account from the web interface.
Is there a way to authorize the API to be able to send a message as an address for a connected account?
No, the API doesn't support this today. It has to do with the scope of the permissions that you consent to. "Allow this app to send mail as you" covers sending from your account, but not from another account, even if you have been granted access.
Another thing you can think about is to leverage App-only authentication. You can configure a Azure AD App to have App-only authentication. After that, all the request will behalf of that app id and you should be able to delegate that app id to send email to anyone on behalf of the user you want.
The following is the steps:
Create a Azure AD application.
Configure your Azure AD Application to allow App-only token by
following Build service and daemon apps in Office 365. You also
need a certificate for app-only token request.
Go to your Azure AD Application->Configuration, Click "Add
application" to add "Office 365 Exchange Online". Select "Send email
as any user" under "Application permission" dropdown box. It allows
your Azure AD App to have permission to send email on behalf of
someone.
Once you have Azure AD application configured, you can refer the
following code for sending email on behalf of a specific user.
string tenantId = "yourtenant.onmicrosoft.com";
string clientId = "your client id";
string resourceId = "https://outlook.office.com/";
string resourceUrl = "https://outlook.office.com/api/v2.0/users/service#contoso.com/sendmail"; //this is your on behalf user's UPN
string authority = String.Format("https://login.windows.net/{1}", AUTHORITYURL, tenantId);
string certificatPath = #"c:\test.pfx"; //this is your certficate location.
string certificatePassword = "xxxx"; // this is your certificate password
var itemPayload = new
{
Message = new
{
Subject = "Test email",
Body = new { ContentType = "Text", Content = "this is test email." },
ToRecipients = new[] { new { EmailAddress = new { Address = "test#cotoso.com" } } }
}
};
//if you need to load from certficate store, use different constructors.
X509Certificate2 certificate = new X509Certificate2(certficatePath, certificatePassword, X509KeyStorageFlags.MachineKeySet);
AuthenticationContext authenticationContext = new AuthenticationContext(authority, false);
ClientAssertionCertificate cac = new ClientAssertionCertificate(clientId, certificate);
//get the access token to Outlook using the ClientAssertionCertificate
var authenticationResult = await authenticationContext.AcquireTokenAsync(resourceId, cac);
string token = authenticationResult.AccessToken;
//initialize HttpClient for REST call
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
client.DefaultRequestHeaders.Add("Accept", "application/json");
//setup the client post
HttpContent content = new StringContent(JsonConvert.SerializeObject(itemPayload));
//Specify the content type.
content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json;odata=verbose");
HttpResponseMessage result = await client.PostAsync(url, content);
if(result.IsSuccessStatusCode)
{
//email send successfully.
}else
{
//email send failed. check the result for detail information from REST api.
}
For a complete explanation, please reference to my blog Send email on behalf of a service account using Office Graph API
I hope it helps and let me know if you have questions.

Resources