Trending Topics: Latest from our forums (July 2022)

Here are some of the latest popular questions that the DocuSign developers community asked on Stack Overflow in the month of July 2022. You too can ask questions by using the tag docusignapi in Stack Overflow.

Thread: How to create an envelope with witness for a recipient

https://stackoverflow.com/questions/73060493/

Summary: The developer is using C# code and wants to create an envelope that has a witness as one of the recipients. They followed the 🐈 blog post which shows how to add recipients, but they want to do that by using a template, which they couldn’t figure out.

Answer: The reason that the developer was unable to complete their task was because the template they were using did not include a witness recipient. However, they can still add a witness to an envelope created from such a template; but they would have to use the Composite Template model, which is a lot more flexible. Here is C# code that can be used to do this:

// DocuSign Builder example. Generated: Fri, 22 Jul 2022 12:34:39 GMT
// DocuSign (c) 2022. MIT License -- https://opensource.org/licenses/MIT
// @see https://developers.docusign.com -- DocuSign Developer Center

using System.Collections.Generic;
using System.IO;
using System;
using DocuSign.eSign.Api;
using DocuSign.eSign.Client;
using DocuSign.eSign.Model;

namespace CSharp_example {
  class Program {
    // Note: the accessToken is for testing and is temporary. It is only good
    // for 8 hours from the time you authenticated with API Request Builder.
    // In production, use an OAuth flow to obtain access tokens.
    private
    const string accessToken = "Eg";
    private
    const string accountId = "";
    private
    const string basePath = "https://demo.docusign.net/restapi";

    // Create the envelope request and send it to DocuSign
    // Returns the resulting envelopeId or ""
    static string SendDocuSignEnvelope() {
      ServerTemplate serverTemplate1 = new ServerTemplate {
        Sequence = "1",
          TemplateId = "xxx-7d29-490d-9bac-xxxxxx"
      };
      List < ServerTemplate > serverTemplates1 = new List < ServerTemplate > {
        serverTemplate1
      };
      Signer signer1 = new Signer {
        ClientUserId = "1001",
          Email = "signer1@example.com",
          Name = "Signer One",
          RecipientId = "1",
          RoleName = "signer1"
      };
      Signer signer2 = new Signer {
        Email = null,
          Name = null,
          RecipientId = "2",
          RoleName = "signer2"
      };
      List < Signer > signers1 = new List < Signer > {
        signer1,
        signer2
      };
      SignHere signHereTab1 = new SignHere {
        AnchorString = "/sig1/",
          AnchorUnits = "pixels",
          AnchorXOffset = "150"
      };
      List < SignHere > signHereTabs1 = new List < SignHere > {
        signHereTab1
      };
      Text textTab1 = new Text {
        AnchorString = "/sig1/",
          AnchorUnits = "pixels",
          AnchorXOffset = "150",
          AnchorYOffset = "12",
          Bold = "true",
          Font = "Helvetica",
          FontSize = "Size14",
          Locked = "true",
          Value = "Witness"
      };
      List < Text > textTabs1 = new List < Text > {
        textTab1
      };
      Tabs tabs1 = new Tabs {
        SignHereTabs = signHereTabs1,
          TextTabs = textTabs1
      };
      Witness witness1 = new Witness {
        RecipientId = "3",
          Tabs = tabs1,
          WitnessFor = "1"
      };
      List < Witness > witnesses1 = new List < Witness > {
        witness1
      };
      Recipients recipients1 = new Recipients {
        Signers = signers1,
          Witnesses = witnesses1
      };
      InlineTemplate inlineTemplate1 = new InlineTemplate {
        Recipients = recipients1,
          Sequence = "2"
      };
      List < InlineTemplate > inlineTemplates1 = new List < InlineTemplate > {
        inlineTemplate1
      };
      CompositeTemplate compositeTemplate1 = new CompositeTemplate {
        InlineTemplates = inlineTemplates1,
          ServerTemplates = serverTemplates1
      };
      List < CompositeTemplate > compositeTemplates1 = new List < CompositeTemplate > {
        compositeTemplate1
      };
      EnvelopeDefinition envelopeDefinition = new EnvelopeDefinition {
        CompositeTemplates = compositeTemplates1,
          Status = "sent"
      };

      ApiClient apiClient = new ApiClient(basePath);
      apiClient.Configuration.AddDefaultHeader("Authorization", "Bearer " + accessToken);
      EnvelopesApi envelopesApi = new EnvelopesApi(apiClient);
      try {
        EnvelopeSummary results = envelopesApi.CreateEnvelope(accountId, envelopeDefinition);
        Console.WriteLine($"Envelope status: {results.Status}. Envelope ID: {results.EnvelopeId}");
        return results.EnvelopeId;
      } catch (ApiException e) {
        Console.WriteLine("Exception while creating envelope!");
        Console.WriteLine($"Code: {e.ErrorCode}\nContent: {e.ErrorContent}");
        //Console.WriteLine(e.Message);
        return "";
      }
    }

    // Request the URL for the recipient view (Signing Ceremony)
    static void RecipientView(string envelopeId) {
      bool doRecipientView = true;
      RecipientViewRequest recipientViewRequest = new RecipientViewRequest {
        AuthenticationMethod = "None",
          ClientUserId = "1001",
          Email = "signer1@example.com",
          UserName = "Signer One"
      };

      if (!doRecipientView || envelopeId == "") {
        return; // EARLY return
      }
      ApiClient apiClient = new ApiClient(basePath);
      apiClient.Configuration.AddDefaultHeader("Authorization", "Bearer " + accessToken);
      EnvelopesApi envelopesApi = new EnvelopesApi(apiClient);
      try {
        ViewUrl results = envelopesApi.CreateRecipientView(accountId, envelopeId, recipientViewRequest);
        Console.WriteLine("Create recipient view succeeded.");
        Console.WriteLine("Open the signing ceremony's long URL within 5 minutes:");
        Console.WriteLine(results.Url);
      } catch (ApiException e) {
        Console.WriteLine("Exception while requesting recipient view!");
        Console.WriteLine($"Code: {e.ErrorCode}\nContent: {e.ErrorContent}");
        //Console.WriteLine(e.Message);
      }
    }

    /// <summary>
    /// This method read bytes content from files in the project's Resources directory
    /// </summary>
    /// <param name="fileName">resource path</param>
    /// <returns>return Base64 encoded content as string</returns>
    internal static string ReadContent(string fileName) {
      byte[] buff = null;
      string path = Path.Combine(Directory.GetCurrentDirectory(), @ "..\..\..\Resources", fileName);
      using(FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read)) {
        using(BinaryReader br = new BinaryReader(stream)) {
          long numBytes = new FileInfo(path).Length;
          buff = br.ReadBytes((int) numBytes);
        }
      }
      return Convert.ToBase64String(buff);
    }

    // The mainline
    static void Main(string[] args) {
      Console.WriteLine("Starting...");
      string envelopeId = SendDocuSignEnvelope();
      RecipientView(envelopeId);
      Console.WriteLine("Done.");
    }
  }
}

Thread: Getting module not found error on docusign-esign package in nodejs

https://stackoverflow.com/questions/73024369/

Summary: This developer is building an integration and trying to run client-side code using the DocuSign eSignature Node SDK (docusign-esign npm package). They are running into some errors.

Answer: The docusign-esign npm package is a server-side-only package. It cannot be used to make API calls directly from the browser (client side). There are other options to making DocuSign API calls from the client, but before you can do that you will need to set up a CORS (Cross Origin Service) gateway. To read more about how to set a CORS gateway, check this blog post. Once you have a CORS gateway, you can use the DocuSign.js embedded JavaScript code to make API calls from the client. Check this blog post to read more about how to use DocuSign.js.

Thread: How to override and skip the recipient authentication screen for specific envelope requests in embedded and remote signing via API?

https://stackoverflow.com/questions/72864234/

Summary: The developer is interested in building an integration that includes embedded signing, but is worried about the users having to authenticate to DocuSign. 

Answer: There are two separate questions to consider when building an integration and thinking about authentication. First, you need to obtain an access token to make API calls. That requires that you authenticate to DocuSign so that the API calls are made in the context of the authenticated user. Then, you allow users to use embedded signing in the application. These users do not need to authenticate (unless you specified some form of recipient authentication) similarly to how remote signers that get the email from DocuSign, by default don’t need to authenticate.

As a developer you must always authenticate your app to make API calls. You could use JWT, where end-users of a web application may not need to authenticate themselves and have a special system account that is used to make API calls. At that point, you could use embedded signing without having the user have to authenticate to DocuSign.

Remember, signers can be anyone; they don’t have to have a DocuSign membership, so they can sign without having to log in. 

Additional resources

Inbar Gazit
Author
Inbar Gazit
Sr. Manager, Developer Content
Published