Docusign nodejs envelopes api returns exports {} - node.js

I'm running the following code in my nodejs server
// Create the recipient view, the Signing Ceremony
let viewRequest: RecipientViewRequest = {
returnUrl: "http://localhost:3000/fund/123?state=123",
authenticationMethod: "none",
email: "my_email",
userName: "Ryan",
clientUserId: "my client user id",
pingFrequency: "600",
pingUrl: "http://localhost:3000"
};
// Call the CreateRecipientView API
// Exceptions will be caught by the calling function
const dsApiClient = new ApiClient();
dsApiClient.setBasePath("https://account-d.docusign.com");
const api = new EnvelopesApi(dsApiClient);
const results = await api.createRecipientView(
"1234",
"5678",
{ recipientViewRequest: viewRequest }
);
and it keeps giving me the output of exports {} no errors or anything. this is pretty painful to debug. has anyone else ran into a similar problem? and how did you fix it?

When you use embedded signing you must set the clientUserId.
But, the clientUserId has to be set when the envelope is created, or when the recipient is added to an a draft envelope and must match the value you later pass in a request for a recipient View.
You cannot make a request for recipient view for an envelope that was created via the web app, unless your code modified that envelope to set the clientUserId for the recipient you want.

Related

DocuSign: Successful envelope but status is not "sent"

I'm using node and I make an envelope with env.status = "sent", I then hit the envelopesApi.createEnvelope with said envelope. The response back says its successful but the status is "created" and no email is sent for signature to the specified signer. What am I missing? Here is the full response
{
"envelopeId": "205ed07d-8094-4031-a334-7159e1bd0f34",
"status": "created",
"statusDateTime": "2023-01-05T06:19:17.9670000Z",
"uri": "/envelopes/205ed07d-8094-4031-a334-7159e1bd0f34"
}
Also note, the simple template has a signer role on it, and a signature specified, in my code I tried both adding the signer with TemplateRole.constructFromObject, and env.templateRoles = [signer1] and also removing this code (as its specified online in the UI), both just result in status created, not sent.
Heres all the relevant code:
async sendEnvelopeFromTemplate(accessToken: string): Promise<any>{
// Data for this method
// args.basePath
// args.accessToken
// args.accountId
const basePath = docusign_account_base_uri + '/restapi'
let dsApiClient = new docusign.ApiClient();
dsApiClient.setBasePath(basePath);
dsApiClient.addDefaultHeader("Authorization", "Bearer " + accessToken);
let envelopesApi = new docusign.EnvelopesApi(dsApiClient);
// Step 1. Make the envelope request body
let envelope = this.makeEnvelope();
// Step 2. call Envelopes::create API method
// Exceptions will be caught by the calling function
try{
let results = await envelopesApi.createEnvelope(docusign_api_account_id, {
envelopeDefinition: envelope,
});
return results;
}
catch(e){
console.log("ERROR")
console.log(e)
}
};
async makeEnvelope() {
const args = {
signerEmail: 'REDACTED',
signerName: 'REDACTED',
templateId: 'REDACTED'
}
// create the envelope definition
let env = new docusign.EnvelopeDefinition();
env.templateId = args.templateId;
// Create template role elements to connect the signer and cc recipients
// to the template
// We're setting the parameters via the object creation
let signer1 = docusign.TemplateRole.constructFromObject({
email: args.signerEmail,
name: args.signerName,
roleName: "signer",
});
// Add the TemplateRole objects to the envelope object
env.templateRoles = [signer1];
env.status = "sent"; // We want the envelope to be sent
return env;
}
You need to set status to "sent" when you create the envelope.
Otherwise (your situation), your envelope is in status "created" which is equivalent to a draft envelope.
Do you have a complete template, i.e. does the template contain a document? An envelope cannot be sent if a) there isn's at least one document in the envelope, b) there must be at least one recipient.
There could be other side issues, such as not allowing "free-form signing" (no tabs specified for the signer) and the envelope has no tabs. But I'm going to assume your account is set up as default so that isn't an issue here. Also assuming you assigned a tab to the role in your template.
Was a simple async issue, I did not await the call to makeEnvelope, I was getting a success back, but the sent status was not being set, as soon as I awaited it the problem went away. Thanks for the other helpful info.
let envelope = this.makeEnvelope();
needed to be
let envelope = await this.makeEnvelope();

.createEnvelope returning 'invalid Template Id'

I'm requesting a signature by email using an existing template.
After using JWT grant for successful authorization, I call the api function docusign.EnvelopesApi(dsApiClient).createEnvelope with a new envelope including my templateId.
The call results in the error: {"errorCode":"TEMPLATE_ID_INVALID","message":"Invalid template ID."}
My server is authorized successfully,
I only have a single docu-sign admin user (myself)
The templateId is correct (i've double and tripped checked)
I'm on a paying account
async function main(){
const args = makeEnvelope({
email: "signer email",
name: "Signer name",
templateId: "some template id",
});
// Make the envelope request body
let envelope = makeEnvelope(args)
let results = await new docusign.EnvelopesApi(dsApiClient).createEnvelope(
accountInfo.apiAccountId, {envelopeDefinition: envelope});
return results;
}
function makeEnvelope(args){
let env = new docusign.EnvelopeDefinition();
env.templateId = args.templateId;
let signer = docusign.TemplateRole.constructFromObject({
email: args.signerEmail,
name: args.signerName,
roleName: 'signer'});
env.templateRoles = [signer];
env.status = "sent";
return env;
}
main();
This error can mean:
TemplateID is just wrong.
TemplateID is from production or developer account, but you are using developer account or production (mismatch)
TemplateID is from a different account then the one you authenticating to.
I cannot tell which one it is, you will have to contact support for this. But instead of just double-checking your ID, you need to also double check the env (prod vs. dev) as well as the accounts, make sure it's from the same account.

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;
}

DocuSign - View Form Data

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.

DocuSign using TemplateID remote signing and Webhook notification for AutoResponded (non-existing signer email)

I'm not getting any webhook notifications for bad email addresses that respond back with unknown mail recipients. I do get a notification email for this but no webhook notification.
envelope code setup
{
var envelopeDefinition = new EnvelopeDefinition()
{
EmailSubject = request.EmailSubject,
EventNotification = new EventNotification()
{
RequireAcknowledgment = "true",
Url = config.Value.EnvelopeEventUrl,
EnvelopeEvents = new List<EnvelopeEvent>
{
//new EnvelopeEvent("Delivered"),
new EnvelopeEvent(EnvelopeEventStatusCode: "Voided"),
new EnvelopeEvent(EnvelopeEventStatusCode: "Declined"),
new EnvelopeEvent(EnvelopeEventStatusCode: "Completed", true.ToString()),
},
RecipientEvents = new List<RecipientEvent>
{
new RecipientEvent(RecipientEventStatusCode:"AuthenticationFailed"),
new RecipientEvent(RecipientEventStatusCode:"AutoResponded"),
new RecipientEvent(RecipientEventStatusCode:"Delivered"),
new RecipientEvent(RecipientEventStatusCode:"Declined"),
new RecipientEvent(RecipientEventStatusCode:"Completed"),
}
},
TemplateId = request.TemplateId,
Status = "Sent",
EmailSettings = new EmailSettings(ReplyEmailAddressOverride: "Reply#xxxxFinance.com.au", ReplyEmailNameOverride: "John Smith"),
};
Sadly this DocuSign link is broken
See Using Webhooks to Track Envelope Status for details
Also I can't login to support using my DocuSign Demo account (Sandbox account), not sure why, so can't log a support ticket!
So, first of - the link is not broken. Not sure what you meant by that.
Second, the issue here may be that sometimes remote servers do not respond back very quickly to let you know an email bounced.
You could try a different strategy where you look for the positive message (that the status of the recipient changed to indicate the email message was sent succsefully) and if you don't get that within say, 5 min - you assume it bounced (but that's on you, sometimes it is just delayed a lot).
See, you subscribed to five different recipient events. The one called "Delivered" is the positive (or opposite) of "AutoResponded" (which may also mean that the person had their Out-Of-Office message on). So, by checking if it was delivered, you can tell when the message got there safely, but not when it bounced for sure.

Resources