DocuSign: Signer Tabs are lost when updating an envelope - c#

When I initially create and sent a DocuSign envelope, I define the tabs where to recipients needs to sign and where the signed date will be placed. This works great with the eSignatures REST API.
When some changes are done in the document (and the envelope status is sent or delivered), the document of the envelope can still be updated.
With the code below I'm able to update the document and email subject/body. After resend, I get the changes made to the email and document correctly.
In the 'new' DocuSign email the signer tabs are lost and I don't have a place to sign.
What I have tried, is to define the signerTabs again and bound it to the recipient.
Update document and email subject/body
envDef.EmailSubject = env.EmailSubject = "Updated documents";
envDef.EmailBlurb = env.EmailBlurb = "Changes were made to the document(s)";
env.Status = EnumHelper.GetDescription(DSStatus.Sent);
envDef.Documents = new List<Document>() { doc };
apiClient.UpdateDocuments(_accountId, envelopeId, envDef);
//resend
apiClient.Update(_accountId, envelopeId, env, new EnvelopesApi.UpdateOptions() { resendEnvelope = true.ToString() });
Signer signer1 = new Signer
{
RecipientId = "1"
};
SignHere signHere1 = new SignHere
{
AnchorString = "/sn1/"
};
Tabs signer1Tabs = new Tabs
{
SignHereTabs = new List<SignHere> { signHere1 },
DateSignedTabs = new List<DateSigned> { dateSigned1 },
FullNameTabs = new List<FullName> { fullName1 }
};
signer1.Tabs = signer1Tabs;
Recipients recipients = new Recipients
{
Signers = new List<Signer> { signer1 },
};
env.Recipients = recipients;
EDIT
This is my request body when sending an envelope. The signer tabs are added with anchorString, in this case /sn1/. So it seems that the updated document no longer has these tabs.
"recipients" : {
"signers" : [ {
"routingOrder" : "1",
"name" : "Recipient Name",
"email" : "Recipient Email Address",
"recipientId" : "1",
"tabs" : {
"signHereTabs" : [ {
"anchorString" : "/sn1/",
} ]
How comes that those signer details are lost, but the envelope is resend to the correct signers again?

so your tabs, how were they created? manually by dragging dropping in the tagger?
You can define them using the API as well. You can GET them for an existing envelope and then "rehydrate" them back to the envelope after you updated it.

Probably, it is common in DocuSign that the tabs of the recipients are lost when updating a document.
To solve this I got the recipients with the tabs included with following call:
apiClient.ListRecipients(_accountId, envelopeId, new EnvelopesApi.ListRecipientsOptions(){ includeTabs = true.ToString() });
This result can be placed in envDef.Recipients.

Related

How to use SMS-Authentication in DocuSign

I'm trying to implement the SMS authentication with the aid of the DocuSign-SDK library.
var signer = new Signer {...};
signer.RequireIdLookup = "true";
signer.IdCheckConfigurationName = "SMS Auth $";
signer.SmsAuthentication = new RecipientSMSAuthentication {
SenderProvidedNumbers = new List<string> {
"0171*******"
}
};
When I try to send this envelope to the DocuSign API it will reply with the following error message:
Error calling CreateEnvelope:
{"errorCode":"INVALIDAUTHENTICATIONSETUP","message":"Recipient phone
number is invalid. Phone number for SMS Authentication: provided is
invalid. }
INVALIDAUTHENTICATIONSETUP: Authentication is not setup correctly for the recipient.
Is there something I have to enable on the DocuSign Admin page? I couldn't find any feature or something like that I need to enable.
Did I implement it the wrong way? Maybe someone can give me some suggestions.
Thanks
BTW: The given phone number should be valid.
EDIT:
When I'm using the new method as #Inbar wrote, I can't get the needed workflowId from the AccountsApi.
var client = new ApiClient(ApiClient.Demo_REST_BasePath);
var token = "eyJ1...";
client.Configuration.DefaultHeader.Add("Authorization", "Bearer " + token);
var accountsApi = new AccountsApi(client);
var response = accountsApi.GetAccountIdentityVerification(accountId);
var result = response.IdentityVerification; // Is empty. Why?
It seems that I have no IdentityVerification options which I can use for the authentication.
How can I enable such IdentityVerification options?
Or what else do I need to pay attention to?
Your code is using the older method, the new method code is provided in GitHub, I'll post it here too. You can find the article on Dev Center.
string workflowId = phoneAuthWorkflow.WorkflowId;
EnvelopeDefinition env = new EnvelopeDefinition()
{
EnvelopeIdStamping = "true",
EmailSubject = "Please Sign",
EmailBlurb = "Sample text for email body",
Status = "Sent"
};
byte[] buffer = System.IO.File.ReadAllBytes(docPdf);
// Add a document
Document doc1 = new Document()
{
DocumentId = "1",
FileExtension = "pdf",
Name = "Lorem",
DocumentBase64 = Convert.ToBase64String(buffer)
};
// Create your signature tab
env.Documents = new List<Document> { doc1 };
SignHere signHere1 = new SignHere
{
AnchorString = "/sn1/",
AnchorUnits = "pixels",
AnchorXOffset = "10",
AnchorYOffset = "20"
};
// Tabs are set per recipient/signer
Tabs signer1Tabs = new Tabs
{
SignHereTabs = new List<SignHere> { signHere1 }
};
string workflowId = workflowId;
RecipientIdentityVerification workflow = new RecipientIdentityVerification()
{
WorkflowId = workflowId,
InputOptions = new List<RecipientIdentityInputOption> {
new RecipientIdentityInputOption
{
Name = "phone_number_list",
ValueType = "PhoneNumberList",
PhoneNumberList = new List<RecipientIdentityPhoneNumber>
{
new RecipientIdentityPhoneNumber
{
Number = phoneNumber,
CountryCode = countryAreaCode,
}
}
}
}
};
Signer signer1 = new Signer()
{
Name = signerName,
Email = signerEmail,
RoutingOrder = "1",
Status = "Created",
DeliveryMethod = "Email",
RecipientId = "1", //represents your {RECIPIENT_ID},
Tabs = signer1Tabs,
IdentityVerification = workflow,
};
Recipients recipients = new Recipients();
recipients.Signers = new List<Signer> { signer1 };
env.Recipients = recipients;
I've created a new developer account on DocuSign and created a small test app in order to request identity verification options. Fortunately, that was working now and I got all available options but I do not understand why this is not working for my other developer account ("old").
When I compare both accounts I don't see the "Identity Verification" setting in the "old" account.
It is possible to activate this "Identity Verification" setting for my "old" dev account?
I guess that enabling this feature would solve the problem.
EDIT:
Ok, I've solved the problem.
I figured out that no IDV was configured for my developer account. In that case, the identity_verification call will return an empty array.
see: https://developers.docusign.com/docs/esign-rest-api/how-to/id-verification/
Also, I have read the following note in the DocuSign documentation:
Note: Phone authentication may not be enabled for some older developer
accounts. If you cannot choose to use phone authentication for your
account, contact support to request access. see:
https://developers.docusign.com/docs/esign-rest-api/esign101/concepts/recipients/auth/#id-verification-idv
So I contacted DocuSign support and they give me access to the IDV accordingly.
Now it is working fine.

Add MS Teams website tab using graph API error

Context:
I am trying to add a new website tab to an existing channel in MS Teams and then get the id of newly-created tab.
Problem:
I am able to create new tab but I am getting a "BadRequest" exception from the Graph:
Message: Value cannot be null. Parameter name: entity
The interesting part is that the tab is created and visible in MS Teams in the correct team and channel but I cannot get it's id in any way.
My code:
var tab = await _graphClient.Teams[teamId].Channels[channelId].Tabs.Request().WithMaxRetry(3).AddAsync(
new TeamsTab
{
DisplayName = "New Tab",
AdditionalData = new Dictionary<string, object>
{
["teamsApp#odata.bind"] =
$"{_teamsFactory.GraphV1Endpoint}/appCatalogs/teamsApps/com.microsoft.teamspace.tab.web"
},
Configuration = new TeamsTabConfiguration
{
EntityId = null,
WebsiteUrl = $"{_appUrl}/1",
ContentUrl = $"{_appUrl}/1",
RemoveUrl = null,
}
}
);
Like I wrote above, this code works and the tab is created but GraphServiceClient throws an exception before the tab variable is assigned.
And when I tried to get the tab list in Graph Explorer
https://graph.microsoft.com/v1.0/teams/{teamid}/channels/{channelid}/tabs
I received an error response:
{
"error": {
"code": "InternalServerError",
"message": "Failed to execute request.",
"innerError": {
"request-id": "a03654e8-37a7-4fbb-8052-6a1b11721234",
"date": "2020-02-24T15:11:54"
}
}
}
I think you might need to set a value for "EntityId" - basically just a string value to uniquely "name" your tab. It's not the "DisplayName", more a string "id" for the tab.
POST https://graph.microsoft.com/v1.0/teams/{id}/channels/{id}/tabs
{
"displayName": "My Contoso Tab",
"teamsApp#odata.bind" : "https://graph.microsoft.com/v1.0/appCatalogs/teamsApps/06805b9e-77e3-4b93-ac81-525eb87513b8",
"configuration": {
"entityId": "2DCA2E6C7A10415CAF6B8AB6661B3154",
"contentUrl": "https://www.contoso.com/Orders/2DCA2E6C7A10415CAF6B8AB6661B3154/tabView",
"websiteUrl": "https://www.contoso.com/Orders/2DCA2E6C7A10415CAF6B8AB6661B3154",
"removeUrl": "https://www.contoso.com/Orders/2DCA2E6C7A10415CAF6B8AB6661B3154/uninstallTab"
}
}
Please take a look at Add Tab to a channel using Graph API
Edit 1: Could you please check you have appropriate permissions to add the Tab?
Edit2: Could you please try below piece of code?
GraphServiceClient graphClient = new GraphServiceClient( authProvider );
var teamsTab = new TeamsTab
{
DisplayName = "WebsiteTab",
AdditionalData = new Dictionary<string, object>()
{
{"teamsApp#odata.bind","https://graph.microsoft.com/v1.0/appCatalogs/teamsApps/com.microsoft.teamspace.tab.web"}
},
Configuration = new TeamsTabConfiguration
{
EntityId = null,
ContentUrl = "https://learn.microsoft.com/en-us/microsoftteams/platform/resources/bot-v3/bots-context",
RemoveUrl = null,
WebsiteUrl = "https://learn.microsoft.com/en-us/microsoftteams/platform/resources/bot-v3/bots-context"
}
};
await graphClient.Teams["TeamId"].Channels["ChannelId"].Tabs
.Request()
.AddAsync(teamsTab);
Finally I found the "solution" though a better name is a workaround for my issue. To make it work I had to set ODataType to null in TeamsTabConfiguration. That's all. The code should look like this:
var tab = await _graphClient.Teams[teamId].Channels[channelId].Tabs.Request().WithMaxRetry(3).AddAsync(
new TeamsTab
{
DisplayName = TabTitle,
ODataBind = $"{_teamsFactory.GraphV1Endpoint}/appCatalogs/teamsApps/com.microsoft.teamspace.tab.web",
Configuration = new TeamsTabConfiguration
{
ODataType = null,
EntityId = null,
WebsiteUrl = $"{_appUrl}/1",
ContentUrl = $"{_appUrl}/1",
RemoveUrl = null
}
});
Like I mentioned it is only a workaround. It is labeled as "service bug" on GitHub (issue#598)

Adding Witness functionality Calling DocuSign

I am using DocuSign(methods in DocuSign.eSign.dll) in c# to implement electronic signature functionality.
I want to add Witness feature similar to the way we do it physically when signing any document.
As per guidelines suggested by DocuSign ,I am using Signer Role as "Specify Recipients" and routing order as "2".
I am using SignHere object as
below
Signer signer = new Signer
{
RoleName = "Specify Recipients",
RoutingOrder = "2"
};
Whenever I call "CreateEnvelope" method exposed by DocuSign, It should give options in email to the recipient to add witness for his documents. Can I know what properties to be set of "Signer" object to achieve this. Or is there any other way to achieve this.
You will need to add that recipient twice, in two separate roles.
A Signer is only able to act on the document. You'll need to create an Agent role for them to be able to specify later recipients.
If you haven't already, you'll also need to add the placeholder Witness role with no name/email defined so that they have a role to fill in.
Signer signer = new Signer
{
Name = signerName,
Email = signerEmail,
RecipientId = "1",
RoutingOrder = "1"
};
Agent agent = new Agent
{
Name = signerName,
Email = signerEmail,
RecipientId = "2",
RoutingOrder = "2"
};
Signer witness = new Signer
{
RoleName = "Witness",
RecipientId = "3",
RoutingOrder = "3",
};
Signer[] signers = new Signer[] { signer, witness };
Agent[] agents = new Agent[] { agent };
Recipients recipients = new Recipients { Signers = new List<Signer>(signers), Agents = new List<Agent>(agents) };
with this setup, the recipient will first get an email invitation to sign the document. Once they complete that, they'll get another invitation to act as the Agent and specify the final recipient. Then the Witness that the user defined will receive their invitation.

Resend Docusign envelope using C#

I'm trying to use code I found here to resend an envelope, but no luck. My code is in two parts. Here's the code on my ASPX page to call a method to resend the envelope:
protected void btnResend_Click(object sender, EventArgs e)
{
Signer signer = new Signer();
signer.Email = txtRecipeintEmail.Text;
signer.Name = txtRecipientName.Text;
Manager mgr = new Manager();
mgr.ResendEnvelope(txtEnvelopeID.Text, signer);
}
Here's the code in the Manager class:
public void ResendEnvelope (string envelopeID, Signer signer)
{
// instantiation of recipients as per https://stackoverflow.com/questions/21565765/resend-docusign-emails
Recipients recipients = new Recipients
{
Signers = new List<Signer>()
{
new Signer
{
RecipientId = "1",
RoleName = "Prospect",
Email = signer.Email,
Name = signer.Name,
},
}
};
string accountID = GetAccountID();
EnvelopesApi api = new EnvelopesApi();
EnvelopesApi.UpdateRecipientsOptions options = new EnvelopesApi.UpdateRecipientsOptions();
options.resendEnvelope = "true";
RecipientsUpdateSummary summary = api.UpdateRecipients(accountID, envelopeID, recipients, options);
var responses = summary.RecipientUpdateResults.ToList<RecipientUpdateResponse>();
var errors = responses.Select(rs => rs.ErrorDetails).ToList();
}
My GetAccountID function works fine - I use it to send the envelope. The value in txtEnvelopeID.Text is set from the code used to send the initial email. I get the initial email.
Here's what I see in errors:
?errors[0].Message
"The specified envelope corrections have duplicate recipients."
?errors[0].ErrorCode
"CORRECTION_HAS_DUPLICATE_RECIPIENTS"
When I tried to set the third argument of UpdateRecipients to null, I got a different error. When I left recipients blank (api.UpdateRecipients(accountID, envelopeID, options: = options)), I got an error.
So, I'm out of new ideas to try. Can anyone help?
The issue you are encountering is that you are creating again a signer that already exists, except that you don't assign the same RecipientId, hence the duplicate error.
Instead of
RecipientId = "1"
You need to make sure you assign the original signer ID, see below :
Signers = new List<Signer>()
{
new Signer
{
RecipientId = signer.RecipientId
},
}
In order to re-send the DocuSign email to your recipients, you can use the UpdateRecipient() method as such (see my C# example below). This will re-trigger the signing email to be sent one more time to the transaction recipients you specify in the recipients parameter :
RecipientsUpdateSummary recipientsUpdateSummary =
envelopeApi.UpdateRecipients(
accountId,
EnvelopeId,
RecipientsToNotifyAgain,
new EnvelopesApi.UpdateRecipientsOptions { resendEnvelope = "true" });
Here is what the official documentation states :

DocusignApi - Attachment with SignHere tab on the third page

I'm using the C# DocuSign SDK to create and send an envelope with a document attached to it. The document has multiple pages, with SignHere tabs appearing in various positions in the document, depending on the recipient. I used Anchor-Tabs to get the SignHere tab to position correctly.
When the recipient receives the document, I see that the SignHere tab was placed at the bottom of every page till it finds the first match for the anchor text. Say for example, the anchor text was on page three, and the document was 5 pages long, SignHere tab would be placed on the bottom of pages 1 and 2, and then correctly placed on page 3. Pages 4 and 5 would have no SignHere tabs (as expected).
I have attached sample / simplified code below:
var envelopeDefinition = new EnvelopeDefinition
{
EmailSubject = "Please sign this agreement.",
Status = "sent",
Documents = new List<Document>(),
Recipients = new Recipients { Signers = new List<Signer>() }
};
envelopeDefinition.Documents.Add(new Document
{
DocumentId = "1", Name = attachment.Name, DocumentBase64 = Convert.ToBase64String(attachment.Bytes),
});
envelopeDefinition.Recipients.Signers.Add(new Signer
{
RecipientId = "1",
Email = recipient.Email,
Name = recipient.Name,
Tabs = new Tabs
{
SignHereTabs = new List<SignHere>
{
new SignHere
{
RecipientId = "1",
AnchorString = "||signhere||",
AnchorXOffset = "1",
AnchorYOffset = "1",
AnchorIgnoreIfNotPresent = "true"
}
}
}
});
var envelopesApi = new EnvelopesApi();
var envelopeSummary = envelopesApi.CreateEnvelope(accountId, envelopeDefinition);
I have a sample attachment uploaded at https://s3-us-west-2.amazonaws.com/sof-docusignq/Test_Attachment.pdf and a completed signed version of the same attachment at https://s3-us-west-2.amazonaws.com/sof-docusignq/Test_Completed.pdf.
What am I doing wrong?
Figured this one out. I used PdfSharp to generate the pdf from my template, PdfSharp apparently has this weird way in which they split content to pages. I switched to EO Pdf and it works great now.

Categories

Resources