AC1111
AC1111

Reputation: 3

DocuSign API Template vs. no Template email response

I am working on an application that uses DocuSign signing in an iframe, housed within a proprietary web app. Signers are able to access the embedded iframe signing view within the same web app.

It was developed without templates in mind. I have implemented the use of templates with building an envelopeDefinition containing the templateKey and respective TemplateRoles. The same "CreateEnvelope" function is called for both non-template and template envelopes, but with different arguments. The Setup page loads in with the template already selected, roles defined, and fields set. The issue arises when the "send" button is clicked.

Without a template, there is no email sent to the signers. It allows for the signers to do so in an embedded form in the proprietary app I am working with. Here is the function used to create an envelope without a template:

public EnvelopeSummary CreateEnvelope(string filePath, string username = null, string emailSubject = null, string brandID = null,List<Models.Recipient> recipients = null)
{
    EnvelopeDefinition envelopeDef = new EnvelopeDefinition
    {
        Status = "created",
        EmailSubject = emailSubject,
        BrandId = brandID
    };

    if (recipients != null)
    {
        List<Signer> signers = recipients.Select(x => new Signer() { Email = x.Email, Name = x.UserName, ClientUserId = x.RecipientID > 50 ? x.RecipientID.ToString() : null, RecipientId = x.RouteOrder.ToString(), RoutingOrder = x.RouteOrder.ToString() }).ToList();
        envelopeDef.Recipients = new Recipients() { Signers = signers };
    }

    return Factory.GetEnvelopesApi(DocuSignConfig).CreateEnvelope(accountId: Helpers.SettingsHelper.AccountID, envelopeDefinition: envelopeDef, options: null);
}

With a template applied, signers are sent an email for an external signature before the workflow has returned to the proprietary app through the return URL of the SenderView. Here is the code used to create an envelope with a template:

public EnvelopeSummary CreateTemplateEnvelope(string filePath,
                                                      List<DataModels.GetRole> roles = null,
                                                      DataModels.GetTemplate template = null,
                                                      string username = null,
                                                      string emailSubject = null,
                                                      string brandID = null,
                                                      List<Models.Recipient> recipients = null)
        {
            EnvelopeDefinition envelopeDef = new EnvelopeDefinition
            {
                Status = "created",
                EmailSubject = emailSubject,
                BrandId = brandID,
                TemplateId = template.TemplateKey
            };

            if (roles != null && recipients != null)
            {
                List<Signer> signers = recipients.Select(x => new Signer() { Email = x.Email, Name = x.UserName, ClientUserId = x.RecipientID > 50 ? x.RecipientID.ToString() : null, RecipientId = x.RouteOrder.ToString(), RoutingOrder = x.RouteOrder.ToString() }).ToList();
                var templateRoles = new List<TemplateRole>();
                int counter = 0;


                foreach (Signer signr in signers)
                {
                    TemplateRole thisSigner = new TemplateRole();
                    thisSigner.Email = signers[counter].Email;
                    thisSigner.Name = signers[counter].Name;
                    thisSigner.RoleName = roles[counter].RoleName;
                    templateRoles.Add(thisSigner);
                    counter++;
                }


                envelopeDef.TemplateRoles = templateRoles;
            }

            return Factory.GetEnvelopesApi(DocuSignConfig).CreateEnvelope(accountId: Helpers.SettingsHelper.AccountID, 
                                                                          envelopeDefinition: envelopeDef, 
                                                                          options: null);
        }

The primary differences are that the template version includes the templateKey, and it uses TemplateRoles rather than Recipients. The template code is a bit more rough than I'd like for a final product, but it's a work in progress just trying to get it running. Does anyone have insight as to how or if it might be possible to create an Envelope and then retain the ability to use embedded signing? Thank you for any help.

EDIT: Solved

As mentioned in the comments to the answer, the issue was solved by properly setting the ClientUserId of each template role based on the Recipient's value for it. This allowed for embedded signing with the template role signers.

Upvotes: 0

Views: 246

Answers (1)

Inbar Gazit
Inbar Gazit

Reputation: 14005

To use a template, you have to first create an envelope from the template. The template itself cannot be sent and so you cannot use embedded signing with the template per-se, only envelopes created from it. Here is code example in seven languages. It shows the first part, to get embedded signing from the resulted envelope you can use this code example.

Here is C# code for you:

 string DoWork (string signerEmail, string signerName, string ccEmail,
    string ccName, string accessToken, string basePath,
    string accountId, string templateId)
{
    // Data for this method
    // signerEmail 
    // signerName
    // ccEmail
    // ccName
    // accessToken
    // basePath
    // accountId
    // templateId

    var config = new Configuration(new ApiClient(basePath));
    config.AddDefaultHeader("Authorization", "Bearer " + accessToken);
    EnvelopesApi envelopesApi = new EnvelopesApi(config);
    EnvelopeDefinition envelope = MakeEnvelope(signerEmail, signerName, ccEmail, ccName, templateId);
    EnvelopeSummary result = envelopesApi.CreateEnvelope(accountId, envelope);
    return result.EnvelopeId;
}
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

    r

eturn viewRequest;
    }
private EnvelopeDefinition MakeEnvelope(string signerEmail, string signerName, 
            string ccEmail, string ccName, string templateId)
        {
            // Data for this method
            // signerEmail 
            // signerName
            // ccEmail
            // ccName
            // templateId

            EnvelopeDefinition env = new EnvelopeDefinition();
            env.TemplateId = templateId;

            TemplateRole signer1 = new TemplateRole();
            signer1.Email = signerEmail;
            signer1.Name =  signerName;
            signer1.RoleName = "signer";
            singer1.ClientUserId = "001";

            TemplateRole cc1 = new TemplateRole();
            cc1.Email = ccEmail;
            cc1.Name = ccName;
            cc1.RoleName = "cc";

            env.TemplateRoles = new List<TemplateRole> { signer1, cc1 };
            env.Status = "sent";
            return env;
        }

Upvotes: 0

Related Questions