dejavuguides
dejavuguides

Reputation: 43

C# DocuSign API: Pulling server template instead of local template document on Docusign

I am currently building a C# project which is functional, but I want to create an embedded envelope from my server template documented (hosted on docusign.com) rather than my local template copy of the document (on my computer).

I'm using the quick start C# code and am getting stuck trying to make it work and replace the "World_Wide_Corp_fields.pdf" default file with a template ID sequence:

Update: Using the eg001 C# code from the Code-Samples-CSharp as the base (instead of the Quick Start C# code).

Below is the combining of eg001 with eg009 so that there is an embedded workflow using a Server Template.

namespace eg_03_csharp_auth_code_grant_core.Views
{
    [Route("eg001")]
    public class Eg001EmbeddedSigningController : EgController
    {
        private string dsPingUrl;
        private string signerClientId = "1000";
        private string dsReturnUrl;

        public Eg001EmbeddedSigningController(DSConfiguration config, IRequestItemsService requestItemsService)
            : base(config, requestItemsService)
        {
            dsPingUrl = config.AppUrl + "/";
            dsReturnUrl = config.AppUrl + "/dsReturn";
            ViewBag.title = "Embedded Signing Ceremony";
        }

        // ***DS.snippet.0.start
        private string DoWork(string signerEmail, string signerName,
            string accessToken, string basePath, string accountId, string templateId)
        {
            // Data for this method
            // signerEmail 
            // signerName
            // accessToken
            // basePath
            // accountId
            // templateId

            // dsPingUrl -- class global
            // signerClientId -- class global
            // dsReturnUrl -- class global

            // Step 1. Create the envelope definition
            EnvelopeDefinition envelope = MakeEnvelope(signerEmail, signerName, ccEmail, ccName, templateId);

            // Step 2. Call DocuSign to create the envelope                   
            var config = new Configuration(new ApiClient(basePath));
            config.AddDefaultHeader("Authorization", "Bearer " + accessToken);
            EnvelopesApi envelopesApi = new EnvelopesApi(config);
            EnvelopeSummary result = envelopesApi.CreateEnvelope(accountId, envelope);
            return result.EnvelopeId;
        }

            // Save for future use within the example launcher
            RequestItemsService.EnvelopeId = envelopeId;

            // Step 3. create the recipient view, the Signing Ceremony
            RecipientViewRequest viewRequest = MakeRecipientViewRequest(signerEmail, signerName);
            // call the CreateRecipientView API
            ViewUrl results1 = envelopesApi.CreateRecipientView(accountId, envelopeId, viewRequest);

            // Step 4. Redirect the user to the Signing Ceremony
            // Don't use an iFrame!
            // State can be stored/recovered using the framework's session or a
            // query parameter on the returnUrl (see the makeRecipientViewRequest method)
            string redirectUrl = results1.Url;
            return redirectUrl;
        }

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

        private EnvelopeDefinition MakeEnvelope(string signerEmail, string signerName, string ccEmail, string ccName, string templateId)
        {
        // Data for this method
        // signerEmail 
        // signerName
        // ccEmail
        // ccName
        // signerClientId -- class global
        // Config.docPdf replaced with templateId

            EnvelopeDefinition envelopeDefinition = new EnvelopeDefinition();
            envelopeDefinition.TemplateId = templateId;
            envelopeDefinition.EmailSubject = "Please sign this document";

            // The order in the docs array determines the order in the envelope
            envelopeDefinition.Documents = new List<Document> { doc1 };

            // Create a signer recipient to sign the document, identified by name and email
            // We set the clientUserId to enable embedded signing for the recipient
            // We're setting the parameters via the object creation
            TemplateRole signer1 = new TemplateRole
            {
                Email = signerEmail,
                Name = signerName,
                ClientUserId = signerClientId,
                RecipientId = "1"
                RoleName = "signer";
             
            TemplateRole cc1 = new TemplateRole();
                cc1.Email = ccEmail;
                cc1.Name = ccName;
                cc1.RoleName = "cc";

            // Create signHere fields (also known as tabs) on the documents,
            // We're using anchor (autoPlace) positioning
            //
            // The DocuSign platform seaches throughout your envelope's
            // documents for matching anchor strings.
            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 }
            };
            signer1.Tabs = signer1Tabs;

            // Add the recipient to the envelope object
            Recipients recipients = new Recipients
            {
                Signers = new List<TemplateRole> { signer1 }
            };
            envelopeDefinition.Recipients = recipients;

            // Request that the envelope be sent by setting |status| to "sent".
            // To request that the envelope be created as a draft, set to "created"
            envelopeDefinition.Status = "sent";

            return envelopeDefinition;
        }
        // ***DS.snippet.0.end


        public override string EgName => "eg001";

        [HttpPost]
        public IActionResult Create(string signerEmail, string signerName)
        {
        // Data for this method
        // signerEmail 
        // signerName
        // dsPingUrl -- class global
        // signerClientId -- class global
        // dsReturnUrl -- class global
        var accessToken = RequestItemsService.User.AccessToken;
        var basePath = RequestItemsService.Session.BasePath + "/restapi";
        var accountId = RequestItemsService.Session.AccountId;
        var templateId = RequestItemsService.TemplateId;


        // Check the token with minimal buffer time.
        bool tokenOk = CheckToken(3);
            if (!tokenOk)
            {
                // We could store the parameters of the requested operation 
                // so it could be restarted automatically.
                // But since it should be rare to have a token issue here,
                // we'll make the user re-enter the form data after 
                // authentication.
                RequestItemsService.EgName = EgName;
                return Redirect("/ds/mustAuthenticate");
            }

            string redirectUrl = DoWork(signerEmail, signerName, accessToken, basePath, accountId, templateId);
            // Redirect the user to the Signing Ceremony
            return Redirect(redirectUrl);
        }
    }
}

References

Upvotes: 1

Views: 762

Answers (1)

Inbar Gazit
Inbar Gazit

Reputation: 14005

There's also a code example for this scenario exactly. Using a template to create an envelope. Here is a snipped of the C# code:

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

            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: 1

Related Questions