Apply Template using .NET SDK - c#

I'm trying to apply a template (not use a template) using the .NET SDK and I can't seem to get it. I have seen one or two other articles on here but neither is using the SDK. Can anyone help me solve this using the SDK?
My situation is this: I have a template defined that contains all of my anchor tags with placement info. When I apply the template via the UI, it works fine and the tags get placed appropriately. When I upload the same document via the API, the tags are not applied.
I have tried to replicate what is shown in these articles using Composite Templates with no success:
How do I apply a server template to envelope document in DocuSign API?
Docusign API - Create envelope, apply template, prefill values
In one of the articles, the OP said the envelope needed to be a Draft. I tried that, but then I haven't been able to change it to "sent" after that.
Here's some of the relevant code from my ASP.NET Web Forms test project. In this project, I'm using a asp:FileUpload control to grab the file contents and then I call the SendFileToDocusign() method:
private void SendFileToDocusign(byte[] fileData, string accessToken)
{
//Create a signer recipient to sign the document, identified by name and email
//We set the clientUserId to enable embedded signing for the recipient
Signer tmpSigner1 = new Signer {
Email = "me#me.com", Name = "Test Tester",
ClientUserId = "1000", RecipientId = "1", RoleName = "Signer1", CustomFields = new List<string> { "Buyer1" }
};
//Step 1. Create the envelope definition
EnvelopeDefinition tmpEnvDef = MakeEnvelopeAndApplyTemplate(fileData, new List<Signer> { tmpSigner1 });
//Step 2. Call DocuSign to create the envelope
ApiClient tmpClient = new ApiClient(DOCUSIGN_API_BASEPATH);
tmpClient.Configuration.AddDefaultHeader("Authorization", "Bearer " + accessToken);
EnvelopesApi tmpEnvelopesApi = new EnvelopesApi(tmpClient);
EnvelopeSummary tmpResults = tmpEnvelopesApi.CreateEnvelope(DOCUSIGN_ACCOUNTID, tmpEnvDef);
string tmpEnvelopeID = tmpResults.EnvelopeId;
//Step 3. create the recipient view, the Signing Ceremony
RecipientViewRequest tmpViewRequest = MakeRecipientViewRequest(tmpSigner1);
//call the CreateRecipientView API
ViewUrl tmpRecipView = tmpEnvelopesApi.CreateRecipientView(DOCUSIGN_ACCOUNTID, tmpEnvelopeID, tmpViewRequest);
Response.Redirect(tmpRecipView.Url);
}
private EnvelopeDefinition MakeEnvelopeAndApplyTemplate(byte[] fileData, List<Signer> signers)
{
EnvelopeDefinition tmpEnv = new EnvelopeDefinition(EmailSubject:"We don't really use the Subject Line here");
Document tmpDoc = new Document();
Recipients tmpRecipients = new Recipients(Signers:signers);
CompositeTemplate tmpCompTemplate = new CompositeTemplate("1");
string tmpfileDataB64 = Convert.ToBase64String(fileData);
tmpDoc.DocumentBase64 = tmpfileDataB64;
tmpDoc.Name = "Test file";//can be different from actual file name
tmpDoc.FileExtension = "pdf";
tmpDoc.DocumentId = "1";
InlineTemplate tmpInlineTemplate = new InlineTemplate();
tmpInlineTemplate.Sequence = "1";
tmpInlineTemplate.Recipients = tmpRecipients;
ServerTemplate tmpServerTemplate = new ServerTemplate("2", DOCUSIGN_TEMPLATE_ID);
tmpCompTemplate.ServerTemplates = new List<ServerTemplate>() { tmpServerTemplate };
tmpCompTemplate.InlineTemplates = new List<InlineTemplate>() { tmpInlineTemplate };
tmpCompTemplate.Document = tmpDoc;
tmpEnv.CompositeTemplates = new List<CompositeTemplate>() { tmpCompTemplate };
//Request that the envelope be sent by setting |status| to "sent".
//To request that the envelope be created as a draft, set to "created"
tmpEnv.Status = "sent";
return tmpEnv;
}
Thanks for any help you can offer.

Your code has to handle the recipients correctly.
The roleName must match between recipients pre-defined in the template and the ones you add in your code.
I don't see in your code that part.
The example you use is for composite template. The relevant code for this is in a regular template example but it's the same.
https://github.com/docusign/code-examples-csharp/blob/master/launcher-csharp/eSignature/Controllers/Eg009UseTemplateController.cs
TemplateRole signer1 = new TemplateRole();
signer1.Email = signerEmail;
signer1.Name = signerName;
signer1.RoleName = "signer";
TemplateRole cc1 = new TemplateRole();
cc1.Email = ccEmail;
cc1.Name = ccName;
cc1.RoleName = "cc";

Related

Interpolate model values into dynamic template using SendGridMessage

I'm building my email for sending with the SendGrid library's SendGridMessage object.
I'm defining my values as an anonymous type which I'm injecting with the SendGridMessage's SetTemplateData() method:
var mail = new SendGridMessage
{
Attachments = new List<Attachment>(),
From = new EmailAddress()
{
Email = emailConfig.FromAddress,
Name = $"Redacted on behalf of {booking.Member.Client.Name}"
},
TemplateId = EmailConstants.ConfirmationEmailTemplateId,
Subject = "Redacted"
};
mail.Personalizations = new List<Personalization>() {
new Personalization() {
Tos = new List<EmailAddress>() {
new EmailAddress() {
Email = memberEmail,
Name = memberName
},
}
}
};
var data = new
{
memberName = memberName,
dateOfAppointment = booking.Date.ToString("dd MMM yy"),
timeOfAppointment = booking.Date.ToString("HH:mm"),
questionnaireLink = questionnaireLink
};
mail.SetTemplateData(data);
The email gets sent out perfectly fine, but in the email template, my tags {memberName}, {dateofAppointment}, etc. are not being replaced by the values indicated here.
I've found handlebars but no C# guide to use them; I'd assume the data I'm submitting above would work so long as I get the tags right in the template... Am I right?
How do I replace the indicated tags ({memberName}, {dateofAppointment}, etc.) in my dynamic template with my data values?
Make sure your template contains tags using double-brace syntax, like {{memberName}}. {memberName} (single braces) won't work.
From the SendGrid docs on Handlebars syntax,
<!-- Template -->
<p>Hello {{ firstName }}</p>
// Test data
{ "firstName": "Ben" }
<!-- Resulting HTML -->
<p>Hello Ben</p>
If this syntax is used properly in the template, the code in your question will work just fine.

How do I send a Sendgrid email using a template and add custom data for the template?

I can send a simple email, I can also send emails using a specific template w/ the TemplateId like the example below, but
QUESTION - How do I send this template below and add or include handlebar data (ex. {"name":"Mike", "url":"some_url", "date":"04/18/2022})?
FYI - I can't find any doc that shows any C# examples. I did find this link to create a transactional template but it doesn't send the email. So not sure here if this is what I'm looking for...
var client = new SendGridClient(Options.SendGridKey);
var msg = new SendGridMessage() {
From = new EmailAddress(fromEmailAddress, fromEmailName),
Subject = subject,
PlainTextContent = message,
HtmlContent = message,
TemplateId = "d-30710e173a174ab58cc641nek3c980d4c"
};
var response = await client.SendEmailAsync(msg);
The solution is that you need to remove the PlainTextContent and HtmlContent properties to make use of the template. Also, you need to provide a dynamicTemplateData object that contains your placeholders.
Here are two code examples that send dynamic template emails with and without the helper class (search for dynamic_template_data and dynamicTemplateData). So the full snippet with the mail helper class would be:
var apiKey = Environment.GetEnvironmentVariable("NAME_OF_THE_ENVIRONMENT_VARIABLE_FOR_YOUR_SENDGRID_KEY");
var client = new SendGridClient(apiKey);
var msg = new SendGridMessage();
msg.SetFrom(new EmailAddress("test#example.com", "Example User"));
msg.AddTo(new EmailAddress("test#example.com", "Example User"));
msg.SetTemplateId("d-d42b0eea09964d1ab957c18986c01828");
var dynamicTemplateData = new ExampleTemplateData
{
Subject = "Hi!",
Name = "Example User",
Location = new Location
{
City = "Birmingham",
Country = "United Kingdom"
}
};
msg.SetTemplateData(dynamicTemplateData);
var response = await client.SendEmailAsync(msg);
PS: Here is the general API documentation that explains the available properties.

CreateEnvelope() throws exception. No message

I am trying to create and send an envelope on the demo environment using the docusign C# API. I am using JWT as my OAuth2 flow. I am able to properly grab the access code needed to authorized my embedded signing.
The function CreateEnvelope fails and throws an exception. The exception shows no information other than that the function failed.
Image of Exception
Has anyone encountered a similar situation before? I have provided a snippet of the code below. Is there anything clearly wrong with how I may be trying to create the envelope?
public static void DocusignFormatter()
{
EnvelopeDefinition envDef = new EnvelopeDefinition();
Document doc = new Document();
doc.DocumentBase64 = System.Convert.ToBase64String(pdfFileInfo.fileBytes);
doc.Name = pdfFileInfo.DocName;
doc.DocumentId = "1";
envDef.Documents = new List<Document>();
envDef.Documents.Add(doc);
envDef.Recipients = new Recipients();
envDef.Recipients.Signers = new List<Signer>();
for (int i = 0; i < signatureFields.Count; i++)
{
Signer signer = new Signer();
signer.Email = docRegistrant.Email;
signer.Name = docApplicants[i].FirstName + " " + docApplicants[i].LastName;
signer.RecipientId = $"{i+1}";
signer.Tabs = new Tabs();
signer.Tabs.SignHereTabs = new List<SignHere>();
List<MyPdfSignatureField> fields;
signatureFields.TryGetValue(i, out fields);
foreach (MyPdfSignatureField field in fields)
{
SignHere signHere = new SignHere();
signHere.DocumentId = "1";
signHere.PageNumber = field.PageNum.ToString();
signHere.RecipientId = i.ToString();
signHere.XPosition = field.XLocation.ToString();
signHere.YPosition = field.YLocation.ToString();
signer.Tabs.SignHereTabs.Add(signHere);
}
envDef.Recipients.Signers.Add(signer);
}
envDef.Status = "created";
ApiClient apiClient = new ApiClient(DocusignHelpers.OAuthBasePath);
Configuration cfi = new Configuration(apiClient);
cfi.AddDefaultHeader("Authorization", "Bearer " + DocusignHelpers.AccessToken);
cfi.AccessToken = DocusignHelpers.AccessToken;
cfi.Password = DocusignHelpers.Password;
EnvelopesApi envelopesApi = new EnvelopesApi(cfi);
EnvelopeSummary envelopeSummary = envelopesApi.CreateEnvelope(DocusignHelpers.AccountId, envDef);
Caught Exception values
you are missing this line:
envDef.EmailSubject = "Test, please sign.";
But that's not the reason for the exception, since you created it as "created" (draft) mode, but it would be the issue once you try to send it.
You may want to confirm the values of all your recipients and ensure you're not sending something that's not an email (for example) in an email field etc.
I solved this friends.
My api url was incorrect.
My key confusion was that the auth endpoints have a separate base url than the rest of the RESTful API.
Authorization url for the demo was: https://account-d.docusign.com
The API client object actually has static fields that contain the urls for the different platforms demo, prod, staging.
I ended up using
ApiClient.Demo_REST_BasePath = "https://demo.docusign.net/restapi"
Thank you all for the replies and help

Error when calling CreateEnvelope: Invalid Username For Recipient

I am using the updated DocuSign API with my .NET application and for the Authentication, I'm using the Authentication Code Grant workflow using 'signature%20extended' as the Code. I can successfully authenticate and get back an access token for the user I'm authenticating with.
I then get the Account details without any issue
ApiClient apiClient = new ApiClient("https://demo.docusign.net/restapi");
var docuSignUserInfo = apiClient.GetUserInfo(accessToken).Accounts.FirstOrDefault();
I then proceed with creating my Signer and Document Model
Document document = new Document
{ DocumentBase64 = Convert.ToBase64String(ReadContent(docName)),
Name = "Lorem Ipsum", FileExtension = "pdf", DocumentId = "1"
};
Document[] documents = new Document[] { document };
// Create the signer recipient object
Signer signer = new Signer
{ Email = "test#example.com", FirstName = "Jane", LastName="Doe" ClientUserId = "1000",
RecipientId = "1", RoutingOrder = "1"
};
Signer[] signers = new Signer[] { signer };
Recipients recipients = new Recipients { Signers = new List<Signer>(signers) };
EnvelopeDefinition envelopeDefinition = new EnvelopeDefinition
{ EmailSubject = "Please sign the document",
Documents = new List<Document>( documents ),
Recipients = recipients,
Status = "sent"
};
ApiClient apiClient = new ApiClient("https://demo.docusign.net/restapi");
apiClient.Configuration.AddDefaultHeader("Authorization", "Bearer " + accessToken);
EnvelopesApi envelopesApi = new EnvelopesApi(apiClient.Configuration);
//This is the API call that throws the error below
EnvelopeSummary results = envelopesApi.CreateEnvelope(accountId, envelopeDefinition);
Error calling CreateEnvelope: {
"errorCode": "INVALID_USERNAME_FOR_RECIPIENT",
"message": "The user name for the recipient is invalid. Envelope definition is missing a UserName for recipientId: 1"
}
From my understanding, I shouldn't need to specify any Username/Passwords as I'm using the Access Token for Authentication. Also, I don't understand why a recipient would require a UserName?
I think you need to provide the Name property for the Signer model. Please try that.
I agree that the FirstName and LastName sound like they are all that is needed, but those attributes may not be fully implemented yet (or a bug).
Please advise if this solved your problem. Thank you.
Added
The FirstName and LastName attributes are optional. DocuSign internal bug report DEVDOCS-1079 has been filed to have the documentation for those fields improved.

Create a WordPress post with private custom fields (_customfieldname) not working

I am creating posts using WordPressSharp, but fail to set private custom field values that begin with an underscore upon creating the post.
I have read a ton of posts about modifying the file meta.php on the WordPress-site to alter register_meta and/or is_protected_meta, but have still not managed to get those custom fields to save the data I pass when creating the post.
using (var client = new WordPressClient(new WordPressSiteConfig
{
BaseUrl = "http://example.com",
Username = "username",
Password = "pass",
BlogId = 1
}))
{
Term t = new Term();
t = client.GetTerm("category", 6);
var terms = new List<Term>();
terms.Add(t);
var customFields = new[]
{
new CustomField
{
Key = "_ct_text_5401d2f94abc9",
Value = "123"
}
};
var post = new Post
{
PostType = "video",
Title = "title",
Content = "description",
PublishDateTime = DateTime.Now,
Status = "draft",
CustomFields = customFields
};
var id = client.NewPost(post);
}
The post is created successfully without issues, but why the private custom field is not getting the value set?
I have tried using both XMLRPC version 3 as well as 2.5, which is a common answer, but it does not apply to this particular issue.
Actually finally found a solution to the issue. I have removed the protection of the custom fields through the addition of the below line to functions.php
add_filter( 'is_protected_meta', '__return_false' );
I do not know if this is the optimal solution security-wise, but it works.

Categories