esign

package module
v0.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 13, 2021 License: BSD-3-Clause Imports: 18 Imported by: 0

README

DocuSign eSignature RestApi v2 and v2.1(Beta) for Go

GoDoc

esign provides Go packages for interacting with DocuSign's eSignature RestApi and has been created using the lastest published swagger definition. Definitions for call payloads and return values are found in {VERSIONID}/model/model.go file.
Docusign has split the API into major categories, and each category has a corresponding package in the v2 and v2.1 directory.

The package requires Go 1.7 or above and has been tested with Go 1.9-1.12.

The previous package github.com/ICGGroup/docusign is now deprecated.

Announcements

eSignature v2.1 and click api are now available.

Resources

Official documentation: https://developers.docusign.com/

Package Updates

All packages, excepte for gen-esign and legacy, are generated from DocuSign's OpenAPI(swagger) specification using the gen-esign package.

Corrections to field names and definitions are documented in gen-esign/overrides/overrides.go.

The package names correspond to the API categories listed on the DocuSign REST API Reference page. Each operation contains an SDK Method which corresponds to the package operation which you will find in operation definition.

Authentication

Authentication is handled by the esign.Credential interface. OAuth2Credentials may be created via the OAuth2Config struct for 3-legged oauth and the JWTConfig struct for 2-legged oauth. Examples are shown for each in the esign examples.

UserID/Password login is available via the legacy.Config which may also be used to create non-expiring oauth tokens (legacy.OauthCredential). Examples are shown in the legacy package.

Models

The model package describes the structure of all data passed to and received from API calls.

Operations

Each package has a service object which is initialized via the .New() call. The service methods define all operations for the package with corresponding options. An operation is executed via a Do(context.Context) function. A context must be passwed for all operation

Example

Create envelope

    import "github.com/ICGGroup/esign"
    import "github.com/ICGGroup/esign/v2/envelope"
    import "github.com/ICGGroup/esign/v2/model"

    sv := envelopes.New(credential)

    f1, err := ioutil.ReadFile("letter.pdf")
    if err != nil {
        return nil, err
    }
    f2, err := ioutil.ReadFile("contract.pdf")
    if err != nil {
        return nil, err
    }

    env := &model.EnvelopeDefinition{
        EmailSubject: "[Go eSignagure SDK] - Please sign this doc",
        EmailBlurb:   "Please sign this test document",
        Status:       "sent",
        Documents: []model.Document{
            {
                DocumentBase64: f1,
                Name:           "invite letter.pdf",
                DocumentID:     "1",
            },
            {
                DocumentBase64: f2,
                Name:           "contract.pdf",
                DocumentID:     "2",
            },
        },
        Recipients: &model.Recipients{
            Signers: []model.Signer{
                {
                    Email:             email,
                    EmailNotification: nil,
                    Name:              name,
                    RecipientID:       "1",
                    Tabs: &model.Tabs{
                        SignHereTabs: []model.SignHere{
                            {
                                TabBase: model.TabBase{
                                    DocumentID:  "1",
                                    RecipientID: "1",
                                },
                                TabPosition: model.TabPosition{
                                    PageNumber: "1",
                                    TabLabel:   "signature",
                                    XPosition:  "192",
                                    YPosition:  "160",
                                },
                            },
                        },
                        DateSignedTabs: []model.DateSigned{
                            {
                                TabBase: model.TabBase{
                                    DocumentID:  "1",
                                    RecipientID: "1",
                                },
                                TabPosition: model.TabPosition{
                                    PageNumber: "1",
                                    TabLabel:   "dateSigned",
                                    XPosition:  "334",
                                    YPosition:  "179",
                                },
                            },
                        },
                        TextTabs: []model.Text{
                            {
                                TabBase: model.TabBase{
                                    DocumentID:  "2",
                                    RecipientID: "1",
                                },
                                TabPosition: model.TabPosition{
                                    PageNumber: "1",
                                    TabLabel:   "txtNote",
                                    XPosition:  "70",
                                    YPosition:  "564",
                                },
                                TabStyle: model.TabStyle{
                                    Name: "This is the tab tooltip",
                                },
                                Width:  300,
                                Height: 150,
                            },
                        },
                    },
                },
            },
        },
    }
    envSummary, err := sv.Create(env).Do(context.Background())

Testing

To test the package with your DocuSign Sandbox, obtain a token from the DocuSign OAuth2 Generator prior to running go test. Set the environment variable DOCUSIGN_Token to the generated access token and run go test. This will read through a list of user folders and all templates.

$ export DOCUSIGN_Token=eyJ0eXAiO...
$ go test

Documentation

Overview

Package esign implements all interfaces of DocuSign's eSignatature REST API as defined in the published api.

Api documentation: https://developers.docusign.com/

Example (Create_envelope)
package main

import (
	"context"
	"io/ioutil"
	"log"

	"github.com/ICGGroup/esign"
	"github.com/ICGGroup/esign/v2.1/envelopes"
	"github.com/ICGGroup/esign/v2.1/model"
)

func getCredential(ctx context.Context, apiUser string) (*esign.OAuth2Credential, error) {
	cfg := &esign.JWTConfig{
		IntegratorKey: "51d1a791-489c-4622-b743-19e0bd6f359e",
		KeyPairID:     "1f57a66f-cc71-45cd-895e-9aaf39d5ccc4",
		PrivateKey: `-----BEGIN RSA PRIVATE KEY-----
		MIICWwIBAAKBgGeDMVfH1+RBI/JMPfrIJDmBWxJ/wGQRjPUm6Cu2aHXMqtOjK3+u
		.........
		ZS1NWRHL8r7hdJL8lQYZPfNqyYcW7C1RW3vWbCRGMA==
		-----END RSA PRIVATE KEY-----`,
		AccountID: "c23357a7-4f00-47f5-8802-94d2b1fb9a29",
		IsDemo:    true,
	}

	return cfg.Credential(apiUser, nil, nil)

}

func main() {
	ctx := context.TODO()
	apiUserID := "78e5a047-f767-41f8-8dbd-10e3eed65c55"
	cred, err := getCredential(ctx, apiUserID)
	if err != nil {
		log.Fatalf("credential error: %v", err)
	}
	sv := envelopes.New(cred)
	f1, err := ioutil.ReadFile("letter.pdf")
	if err != nil {
		log.Fatalf("file read error: %v", err)
	}

	env := &model.EnvelopeDefinition{
		EmailSubject: "[Go eSignagure SDK] - Please sign this doc",
		EmailBlurb:   "Please sign this test document",
		Status:       "sent",
		Documents: []model.Document{
			{
				DocumentBase64: f1,
				Name:           "invite letter.pdf",
				DocumentID:     "1",
			},
		},
		Recipients: &model.Recipients{
			Signers: []model.Signer{
				{
					Email:             "user@example.com",
					EmailNotification: nil,
					Name:              "J F Cote",
					RecipientID:       "1",
					Tabs: &model.Tabs{
						SignHereTabs: []model.SignHere{
							{
								TabBase: model.TabBase{
									DocumentID:  "1",
									RecipientID: "1",
								},
								TabPosition: model.TabPosition{
									PageNumber: "1",
									TabLabel:   "signature",
									XPosition:  "192",
									YPosition:  "160",
								},
							},
						},
						DateSignedTabs: []model.DateSigned{
							{
								TabBase: model.TabBase{
									DocumentID:  "1",
									RecipientID: "1",
								},
								TabPosition: model.TabPosition{
									PageNumber: "1",
									TabLabel:   "dateSigned",
									XPosition:  "334",
									YPosition:  "179",
								},
							},
						},
					},
				},
			},
		},
	}
	envSummary, err := sv.Create(env).Do(ctx)
	if err != nil {
		log.Fatalf("create envelope error: %v", err)
	}
	log.Printf("New envelope id: %s", envSummary.EnvelopeID)
}
Output:

Example (Create_envelope_fileupload)
package main

import (
	"context"
	"log"
	"os"

	"github.com/ICGGroup/esign"
	"github.com/ICGGroup/esign/v2.1/envelopes"
	"github.com/ICGGroup/esign/v2.1/model"
)

func getCredential(ctx context.Context, apiUser string) (*esign.OAuth2Credential, error) {
	cfg := &esign.JWTConfig{
		IntegratorKey: "51d1a791-489c-4622-b743-19e0bd6f359e",
		KeyPairID:     "1f57a66f-cc71-45cd-895e-9aaf39d5ccc4",
		PrivateKey: `-----BEGIN RSA PRIVATE KEY-----
		MIICWwIBAAKBgGeDMVfH1+RBI/JMPfrIJDmBWxJ/wGQRjPUm6Cu2aHXMqtOjK3+u
		.........
		ZS1NWRHL8r7hdJL8lQYZPfNqyYcW7C1RW3vWbCRGMA==
		-----END RSA PRIVATE KEY-----`,
		AccountID: "c23357a7-4f00-47f5-8802-94d2b1fb9a29",
		IsDemo:    true,
	}

	return cfg.Credential(apiUser, nil, nil)

}

func main() {
	ctx := context.TODO()
	apiUserID := "78e5a047-f767-41f8-8dbd-10e3eed65c55"
	cred, err := getCredential(ctx, apiUserID)
	if err != nil {
		log.Fatalf("credential error: %v", err)
	}
	// open files for upload
	f1, err := os.Open("letter.pdf")
	if err != nil {
		log.Fatalf("file open letter.pdf: %v", err)
	}
	f2, err := os.Open("contract.pdf")
	if err != nil {
		log.Fatalf("file open contract.pdf: %v", err)
	}

	sv := envelopes.New(cred)

	env := &model.EnvelopeDefinition{
		EmailSubject: "[Go eSignagure SDK] - Please sign this doc",
		EmailBlurb:   "Please sign this test document",
		Status:       "sent",
		Documents: []model.Document{
			{
				Name:       "invite letter.pdf",
				DocumentID: "1",
			},
			{
				Name:       "contract.pdf",
				DocumentID: "2",
			},
		},
		Recipients: &model.Recipients{
			Signers: []model.Signer{
				{
					Email:             "user@example.com",
					EmailNotification: nil,
					Name:              "J F Cote",
					RecipientID:       "1",
					Tabs: &model.Tabs{
						SignHereTabs: []model.SignHere{
							{
								TabBase: model.TabBase{
									DocumentID:  "1",
									RecipientID: "1",
								},
								TabPosition: model.TabPosition{
									PageNumber: "1",
									TabLabel:   "signature",
									XPosition:  "192",
									YPosition:  "160",
								},
							},
						},
						DateSignedTabs: []model.DateSigned{
							{
								TabBase: model.TabBase{
									DocumentID:  "1",
									RecipientID: "1",
								},
								TabPosition: model.TabPosition{
									PageNumber: "1",
									TabLabel:   "dateSigned",
									XPosition:  "334",
									YPosition:  "179",
								},
							},
						},
						TextTabs: []model.Text{
							{
								TabBase: model.TabBase{
									DocumentID:  "2",
									RecipientID: "1",
								},
								TabPosition: model.TabPosition{
									PageNumber: "1",
									TabLabel:   "txtNote",
									XPosition:  "70",
									YPosition:  "564",
								},
								TabStyle: model.TabStyle{
									Name: "This is the tab tooltip",
								},
								Width:  "300",
								Height: "150",
							},
						},
					},
				},
			},
		},
	}
	// UploadFile.Reader is always closed on operation
	envSummary, err := sv.Create(env, &esign.UploadFile{
		ContentType: "application/pdf",
		FileName:    "invitation letter.pdf",
		ID:          "1",
		Reader:      f1,
	}, &esign.UploadFile{
		ContentType: "application/pdf",
		FileName:    "contract.pdf",
		ID:          "2",
		Reader:      f2,
	}).Do(ctx)

	if err != nil {
		log.Fatalf("create envelope error: %v", err)
	}
	log.Printf("New envelope id: %s", envSummary.EnvelopeID)

}
Output:

Example (Document_download)
package main

import (
	"context"
	"io"
	"log"
	"os"

	"github.com/ICGGroup/esign"
	"github.com/ICGGroup/esign/v2.1/envelopes"
)

func getCredential(ctx context.Context, apiUser string) (*esign.OAuth2Credential, error) {
	cfg := &esign.JWTConfig{
		IntegratorKey: "51d1a791-489c-4622-b743-19e0bd6f359e",
		KeyPairID:     "1f57a66f-cc71-45cd-895e-9aaf39d5ccc4",
		PrivateKey: `-----BEGIN RSA PRIVATE KEY-----
		MIICWwIBAAKBgGeDMVfH1+RBI/JMPfrIJDmBWxJ/wGQRjPUm6Cu2aHXMqtOjK3+u
		.........
		ZS1NWRHL8r7hdJL8lQYZPfNqyYcW7C1RW3vWbCRGMA==
		-----END RSA PRIVATE KEY-----`,
		AccountID: "c23357a7-4f00-47f5-8802-94d2b1fb9a29",
		IsDemo:    true,
	}

	return cfg.Credential(apiUser, nil, nil)

}

func main() {

	ctx := context.TODO()
	envID := "78e5a047-f767-41f8-8dbd-10e3eed65c55"
	cred, err := getCredential(ctx, envID)
	if err != nil {
		log.Fatalf("credential error: %v", err)
	}
	sv := envelopes.New(cred)

	var dn *esign.Download
	if dn, err = sv.DocumentsGet("combined", envID).
		Certificate().
		Watermark().
		Do(ctx); err != nil {

		log.Fatalf("DL: %v", err)
	}
	defer dn.Close()
	log.Printf("File Type: %s  Length: %d", dn.ContentType, dn.ContentLength)
	f, err := os.Create("ds_env.pdf")
	if err != nil {
		log.Fatalf("file create: %v", err)
	}
	defer f.Close()
	if _, err := io.Copy(f, dn); err != nil {
		log.Fatalf("file create: %v", err)
	}

}
Output:

Index

Examples

Constants

This section is empty.

Variables

View Source
var ClickV1 = &APIVersion{
	Version: "v1",
	Prefix:  "clickapi",
}

ClickV1 defines url replacement for clickraps api

View Source
var ErrNilOp = errors.New("nil operation")

ErrNilOp used to indicate a nil operation pointer

View Source
var VersionV21 = &APIVersion{Version: "v2.1"}

VersionV21 indicates that the url will resolve to /restapi/v2.1

Functions

This section is empty.

Types

type APIVersion

type APIVersion struct {
	Version string
	Prefix  string
}

APIVersion defines the prefix used to resolve an operation's url. If nil or blank, "v2" is assumed.

func (*APIVersion) ResolveDSURL

func (v *APIVersion) ResolveDSURL(u *url.URL, host string, accountID string) *url.URL

ResolveDSURL updates the passed *url.URL's settings. https://developers.docusign.com/esign-rest-api/guides/authentication/user-info-endpoints#form-your-base-path

type AdminConsentResponse

type AdminConsentResponse struct {
	Issuer    string   `json:"iss"`       // domain of integration key
	Audience  string   `json:"aud"`       // the integrator key (also known as client ID) of the application
	ExpiresAt int64    `json:"exp"`       // the datetime when the ID token will expire, in Unix epoch format
	IssuedAt  int64    `json:"iat"`       // the datetime when the ID token was issued, in Unix epoch format
	Subject   string   `json:"sub"`       //  user ID of the admin granting consent for the organization users
	SiteID    int64    `json:"siteid"`    // identifies the docusign server used.
	AuthTime  string   `json:"auth_time"` // The unix epoch datetime when the ID token was created.
	AMR       []string `json:"amr"`       // how the user authenticated
	COID      []string `json:"coid"`      //  list of organization IDs for the organizations whose admin has granted consent
}

AdminConsentResponse is the response sent to the redirect url of and external admin consent https://developers.docusign.com/esign-rest-api/guides/authentication/obtaining-consent#admin-consent-for-external-applications

type ConnectData

type ConnectData struct {
	EnvelopeStatus EnvelopeStatusXML `xml:"EnvelopeStatus" json:"envelopeStatus,omitempty"`
	DocumentPdfs   []DocumentPdfXML  `xml:"DocumentPDFs>DocumentPDF" json:"documentPdfs,omitempty"`
}

ConnectData is the top level definition of a Connect status message.

type Credential

type Credential interface {
	// AuthDo attaches an authorization header to a request, prepends
	// account and user ids to url, and sends request.  This func must
	// always close the request Body.
	AuthDo(context.Context, *http.Request, *APIVersion) (*http.Response, error)
}

Credential adds an authorization header(s) for the http request, resolves the http client and finalizes the url. Credentials may be created using the Oauth2Config and JWTConfig structs as well as legacy.Config.

type CustomFieldXML

type CustomFieldXML struct {
	Name     string `xml:"Name" json:"name,omitempty"`
	Value    string `xml:"Value" json:"value,omitempty"`
	Show     bool   `xml:"Show" json:"show,omitempty"`
	Required bool   `xml:"Required" json:"required,omitempty"`
}

CustomFieldXML contains the name and values of a custom field.

type DSTime

type DSTime string

DSTime handles the multiple datetime formats that DS returns in the Connect service.

func (*DSTime) Time

func (d *DSTime) Time() time.Time

Time converts a DSTime value into a time.time. On error or unknown format, the zero value of time.Time is returned.

type DocumentPdfXML

type DocumentPdfXML struct {
	Name     string `xml:"Name" json:"name,omitempty"`
	PDFBytes string `xml:"PDFBytes" json:"pdfBytes,omitempty"`
}

DocumentPdfXML contains the base64 enocded pdf files.

type DocumentStatusXML

type DocumentStatusXML struct {
	ID           string `xml:"ID" json:"id,omitempty"`
	Name         string `xml:"Name" json:"name,omitempty"`
	TemplateName string `xml:"TemplateName" json:"templateName,omitempty"`
	Sequence     string `xml:"Sequence" json:"sequence,omitempty"`
}

DocumentStatusXML describes each document in the envelope.

type Download

type Download struct {
	io.ReadCloser
	// ContentLength from response
	ContentLength int64
	// ContentType header value
	ContentType string
}

Download is used to return image and pdf files from DocuSign. The developer needs to ensure to close when finished reading.

type EnvelopeStatusXML

type EnvelopeStatusXML struct {
	TimeGenerated      *DSTime              `xml:"TimeGenerated" json:"timeGenerated,omitempty"`
	EnvelopeID         string               `xml:"EnvelopeID" json:"envelopeID,omitempty"`
	Subject            string               `xml:"Subject" json:"subject,omitempty"`
	UserName           string               `xml:"UserName" json:"userName,omitempty"`
	Email              string               `xml:"Email" json:"email,omitempty"`
	Status             string               `xml:"Status" json:"status,omitempty"`
	Created            *DSTime              `xml:"Created" json:"created,omitempty"`
	Sent               *DSTime              `xml:"Sent" json:"sent,omitempty"`
	Delivered          *DSTime              `xml:"Delivered" json:"delivered,omitempty"`
	Signed             *DSTime              `xml:"Signed" json:"signed,omitempty"`
	Completed          *DSTime              `xml:"Completed" json:"completed,omitempty"`
	ACStatus           string               `xml:"ACStatus" json:"acStatus,omitempty"`
	ACStatusDate       string               `xml:"ACStatusDate" json:"acStatusDate,omitempty"`
	ACHolder           string               `xml:"ACHolder" json:"acHolder,omitempty"`
	ACHolderEmail      string               `xml:"ACHolderEmail" json:"acHolderEmail,omitempty"`
	ACHolderLocation   string               `xml:"ACHolderLocation" json:"acHolderLocation,omitempty"`
	SigningLocation    string               `xml:"SigningLocation" json:"signingLocation,omitempty"`
	SenderIPAddress    string               `xml:"SenderIPAddress" json:"senderIPAddress,omitempty"`
	EnvelopePDFHash    string               `xml:"EnvelopePDFHash" json:"envelopePDFHash,omitempty"`
	AutoNavigation     bool                 `xml:"AutoNavigation" json:"autoNavigation,omitempty"`
	EnvelopeIDStamping bool                 `xml:"EnvelopeIdStamping" json:"envelopeIdStamping,omitempty"`
	AuthoritativeCopy  bool                 `xml:"AuthoritativeCopy" json:"authoritativeCopy,omitempty"`
	VoidReason         string               `xml:"VoidReason" json:"voidReason,omitempty"`
	RecipientStatuses  []RecipientStatusXML `xml:"RecipientStatuses>RecipientStatus" json:"recipientStatuses,omitempty"`
	CustomFields       []CustomFieldXML     `xml:"CustomFields>CustomField" json:"customFields,omitempty"`
	DocumentStatuses   []DocumentStatusXML  `xml:"DocumentStatuses>DocumentStatus" json:"documentStatuses,omitempty"`
}

EnvelopeStatusXML contains envelope information.

type JWTConfig

type JWTConfig struct {
	// see https://developers.docusign.com/esign-rest-api/guides/authentication/oauth2-jsonwebtoken#prerequisites
	IntegratorKey string `json:"integrator_key,omitempty"`
	// Use developer sandbox
	IsDemo bool `json:"is_demo,omitempty"`
	// PEM encoding of an RSA Private Key.
	// see https://developers.docusign.com/esign-rest-api/guides/authentication/oauth2-jsonwebtoken#prerequisites
	// for how to create RSA keys to the application.
	PrivateKey string `json:"private_key,omitempty"`
	KeyPairID  string `json:"key_pair_id,omitempty"`
	// DocuSign users may have more than one account.  If AccountID is
	// not set then the user's default account will be used.
	AccountID string `json:"account_id,omitempty"`
	// Options can specify how long the token will be valid. DocuSign
	// limits this to 1 hour.  1 hour is assumed if left empty.  Offsets
	// for expiring token may also be used.  Do not set FormValues or Custom Claims.
	Options *jwt.ConfigOptions `json:"expires,omitempty"`
	// if not nil, CacheFunc is called after a new token is created passing
	// the newly created Token and UserInfo.
	CacheFunc func(context.Context, oauth2.Token, UserInfo) `json:"-"`
	// HTTPClientFunc determines client used for oauth2 token calls.  If
	// nil, ctxclient.DefaultClient will be used.
	HTTPClientFunc ctxclient.Func `json:"-"`
}

JWTConfig is used to create an OAuth2Credential based upon DocuSign's Service Integration Authentication.

See https://developers.docusign.com/esign-rest-api/guides/authentication/oauth2-jsonwebtoken

Example
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/ICGGroup/esign"
	"github.com/ICGGroup/esign/v2.1/folders"
)

func main() {
	ctx := context.TODO()
	cfg := &esign.JWTConfig{
		IntegratorKey: "51d1a791-489c-4622-b743-19e0bd6f359e",
		KeyPairID:     "1f57a66f-cc71-45cd-895e-9aaf39d5ccc4",
		PrivateKey: `-----BEGIN RSA PRIVATE KEY-----
		MIICWwIBAAKBgGeDMVfH1+RBI/JMPfrIJDmBWxJ/wGQRjPUm6Cu2aHXMqtOjK3+u
		.........
		ZS1NWRHL8r7hdJL8lQYZPfNqyYcW7C1RW3vWbCRGMA==
		-----END RSFolderA PRIVATE KEY-----`,
		AccountID: "c23357a7-4f00-47f5-8802-94d2b1fb9a29",
		IsDemo:    true,
	}

	apiUserName := "78e5a047-f767-41f8-8dbd-10e3eed65c55"
	credential, err := cfg.Credential(apiUserName, nil, nil)
	if err != nil {
		log.Fatalf("create credential error: %v", err)
	}
	fl, err := folders.New(credential).List().Do(ctx)
	if err != nil {
		log.Fatalf("Folder list error: %v", err)
	}
	for _, fld := range fl.Folders {
		fmt.Printf("%s: %s", fld.Name, fld.FolderID)
	}
}
Output:

func (*JWTConfig) Credential

func (c *JWTConfig) Credential(apiUserName string, token *oauth2.Token, u *UserInfo, scopes ...string) (*OAuth2Credential, error)

Credential returns an *OAuth2Credential. The passed token will be refreshed as needed. If no scopes listed, signature is assumed.

func (*JWTConfig) ExternalAdminConsentURL

func (c *JWTConfig) ExternalAdminConsentURL(redirectURL, authType, state string, prompt bool, scopes ...string) (string, error)

ExternalAdminConsentURL creates a url for beginning external admin consent workflow. See https://developers.docusign.com/esign-rest-api/guides/authentication/obtaining-consent#admin-consent-for-external-applications for details.

redirectURL is the URI to which DocuSign will redirect the browser after authorization has been granted by the extneral organization's admin. The redirect URI must exactly match one of those pre-registered for the Integrator Key in your DocuSign account.

authType may be either code (Authorization Code grant) or token (implicit grant).

state holds an optional value that is returned with the authorization code.

prompt determines whether the user is prompted for re-authentication, even with an active login session.

scopes permissions being requested for the application from each user in the organization. Valid values are

signature — allows your application to create and send envelopes, and obtain links for starting signing sessions.
extended — issues your application a refresh token that can be used any number of times (Authorization Code flow only).
impersonation — allows your application to access a user’s account and act on their behalf via JWT authentication.

func (*JWTConfig) UserConsentURL

func (c *JWTConfig) UserConsentURL(redirectURL string, scopes ...string) string

UserConsentURL creates a url allowing a user to consent to impersonation https://developers.docusign.com/esign-rest-api/guides/authentication/obtaining-consent#individual-consent

Example
package main

import (
	"context"
	"log"

	"github.com/ICGGroup/esign"
)

func main() {
	// Prior to allowing jwt impersonation, each user must
	// provide consent.  Use the JWTConfig.UserConsentURL
	// to provide a url for individual to provide their
	// consent to DocuSign.
	apiUserID := "78e5a047-f767-41f8-8dbd-10e3eed65c55"

	cfg := &esign.JWTConfig{
		IntegratorKey: "51d1a791-489c-4622-b743-19e0bd6f359e",
		KeyPairID:     "1f57a66f-cc71-45cd-895e-9aaf39d5ccc4",
		PrivateKey: `-----BEGIN RSA PRIVATE KEY-----
		MIICWwIBAAKBgGeDMVfH1+RBI/JMPfrIJDmBWxJ/wGQRjPUm6Cu2aHXMqtOjK3+u
		.........
		ZS1NWRHL8r7hdJL8lQYZPfNqyYcW7C1RW3vWbCRGMA==
		-----END RSA PRIVATE KEY-----`,
		AccountID: "c23357a7-4f00-47f5-8802-94d2b1fb9a29",
		IsDemo:    true,
	}

	// the redirURL must match one entered in DocuSign's Edit API
	// Integrator Key screen.
	consentURL := cfg.UserConsentURL("https://yourdomain.com/auth")
	_ = consentURL
	// redirect user to consentURL.  Once users given consent, a JWT
	// credential may be used to impersonate the user.  This only has
	// to be done once.
	ctx := context.TODO()
	cred, err := cfg.Credential(apiUserID, nil, nil)
	if err != nil {
		log.Fatalf("%v", err)
	}
	u, err := cred.UserInfo(ctx)
	if err != nil {
		log.Fatalf("%v", err)
	}
	log.Printf("%s", u.Name)

}
Output:

type NmValXML

type NmValXML struct {
	Name  string `xml:"name,attr" json:"name,omitempty"`
	Value string `xml:"value" json:"value,omitempty"`
}

NmValXML contains the key/value pair for the form values.

type OAuth2Config

type OAuth2Config struct {
	// see "Create integrator key and configure settings" at
	// https://developers.docusign.com/esign-rest-api/guides
	IntegratorKey string `json:"integrator_key,omitempty"`
	// Secret generated when setting up integration in DocuSign. Leave blank for
	// implicit grant.
	Secret string `json:"secret,omitempty"`
	// The redirect URI must exactly match one of those pre-registered for the
	// integrator key. This determines where to redirect the user after they
	// successfully authenticate.
	RedirURL string `json:"redir_url,omitempty"`
	// DocuSign users may have more than one account.  If AccountID is
	// not set then the user's default account will be used.
	AccountID string `json:"account_id,omitempty"`
	// if not nil, CacheFunc is called after a new token is created passing
	// the newly created Token and UserInfo.
	CacheFunc func(context.Context, oauth2.Token, UserInfo) `json:"cache_func,omitempty"`
	// Prompt indicates whether the authentication server will prompt
	// the user for re-authentication, even if they have an active login session.
	Prompt bool `json:"prompt,omitempty"`
	// List of the end-user’s preferred languages, represented as a
	// space-separated list of RFC5646 language tag values ordered by preference.
	// Note: can no longer find in docusign documentation.
	UIlocales []string `json:"u_ilocales,omitempty"`
	// Set to true to obtain an extended lifetime token (i.e. contains refresh token)
	ExtendedLifetime bool `json:"extended_lifetime,omitempty"`
	// Use developer sandbox
	IsDemo bool `json:"is_demo,omitempty"`
	// determines client used for oauth2 token calls.  If
	// nil, ctxclient.Default will be used.
	HTTPClientFunc ctxclient.Func `json:"-"`
}

OAuth2Config allows for 3-legged oauth via a code grant mechanism see https://developers.docusign.com/esign-rest-api/guides/authentication/oauth2-code-grant

Example
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/ICGGroup/esign"
	"github.com/ICGGroup/esign/v2.1/folders"
)

func main() {
	ctx := context.TODO()
	cfg := &esign.OAuth2Config{
		IntegratorKey:    "51d1a791-489c-4622-b743-19e0bd6f359e",
		Secret:           "f625e6f7-48e3-4226-adc5-66e434b21355",
		RedirURL:         "https://yourdomain.com/auth",
		AccountID:        "c23357a7-4f00-47f5-8802-94d2b1fb9a29",
		ExtendedLifetime: true,
		IsDemo:           true,
	}
	state := "SomeRandomStringOfSufficientSize"

	authURL := cfg.AuthURL(state)
	// Redirect user to consent page.
	fmt.Printf("Visit %s", authURL)

	// Enter code returned to redirectURL.
	var code string
	if _, err := fmt.Scan(&code); err != nil {
		log.Fatal(err)
	}
	credential, err := cfg.Exchange(ctx, code)
	if err != nil {
		log.Fatal(err)
	}
	fl, err := folders.New(credential).List().Do(ctx)
	if err != nil {
		log.Fatalf("Folder list error: %v", err)
	}
	for _, fld := range fl.Folders {
		fmt.Printf("%s: %s", fld.Name, fld.FolderID)
	}

}
Output:

func (*OAuth2Config) AuthURL

func (c *OAuth2Config) AuthURL(state string, scopes ...string) string

AuthURL returns a URL to DocuSign's OAuth 2.0 consent page with all appropriate query parmeters for starting 3-legged OAuth2Flow.

If scopes are empty, {"signature"} is assumed.

State is a token to protect the user from CSRF attacks. You must always provide a non-zero string and validate that it matches the the state query parameter on your redirect callback.

func (*OAuth2Config) Credential

func (c *OAuth2Config) Credential(tk *oauth2.Token, u *UserInfo) (*OAuth2Credential, error)

Credential returns an *OAuth2Credential using the passed oauth2.Token as the starting authorization token.

func (*OAuth2Config) Exchange

func (c *OAuth2Config) Exchange(ctx context.Context, code string) (*OAuth2Credential, error)

Exchange converts an authorization code into a token.

It is used after a resource provider redirects the user back to the Redirect URI (the URL obtained from AuthCodeURL).

The code will be in the *http.Request.FormValue("code"). Before calling Exchange, be sure to validate FormValue("state").

type OAuth2Credential

type OAuth2Credential struct {
	ctxclient.Func
	// contains filtered or unexported fields
}

OAuth2Credential authorizes op requests via DocuSign's oauth2 protocol.

func TokenCredential

func TokenCredential(accessToken string, isDemo bool) *OAuth2Credential

TokenCredential create a static credential without refresh capabilities. When the token expires, ops will receive a 401 error,

Example
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/ICGGroup/esign"
	"github.com/ICGGroup/esign/v2.1/folders"
)

func main() {
	// retrieve token frm DocuSign OAuthGenerator
	// https://developers.docusign.com/oauth-token-generator
	// or generate or
	var accessToken = `eyJ0eXAiOiJNVCIsImF...`
	credential := esign.TokenCredential(accessToken, true)
	fl, err := folders.New(credential).List().Do(context.Background())
	if err != nil {
		log.Fatalf("Folder list error: %v", err)
	}
	for _, fld := range fl.Folders {
		fmt.Printf("%s: %s", fld.Name, fld.FolderID)
	}
}
Output:

func (*OAuth2Credential) AuthDo

func (cred *OAuth2Credential) AuthDo(ctx context.Context, req *http.Request, v *APIVersion) (*http.Response, error)

AuthDo set the authorization header and completes request's url with the users's baseURI and account id before sending the request

func (*OAuth2Credential) SetCacheFunc

func (cred *OAuth2Credential) SetCacheFunc(f func(context.Context, oauth2.Token, UserInfo)) *OAuth2Credential

SetCacheFunc safely replaces the caching function for the credential

func (*OAuth2Credential) SetClientFunc

func (cred *OAuth2Credential) SetClientFunc(f ctxclient.Func) *OAuth2Credential

SetClientFunc safely replaces the ctxclient.Func for the credential

func (*OAuth2Credential) Token

func (cred *OAuth2Credential) Token(ctx context.Context) (*oauth2.Token, error)

Token checks where the cachedToken is valid. If not it attempts to obtain a new token via the refresher. Next accountID and baseURI are updated if blank, (see https://developers.docusign.com/esign-rest-api/guides/authentication/user-info-endpoints).

func (*OAuth2Credential) UserInfo

func (cred *OAuth2Credential) UserInfo(ctx context.Context) (*UserInfo, error)

UserInfo returns user data returned from the /oauth/userinfo ednpoint. See https://developers.docusign.com/esign-rest-api/guides/authentication/user-info-endpoints

func (*OAuth2Credential) WithAccountID

func (cred *OAuth2Credential) WithAccountID(accountID string) *OAuth2Credential

WithAccountID creates a copy the current credential with a new accountID. An empty accountID indicates the user's default account. If the accountID is invalid for the user an error will occur when authorizing an operation. Check for valid account using *OAuth2Credential.UserInfo(ctx).

type Op

type Op struct {
	// Used for authorization and for URL completion
	Credential Credential
	// POST,GET,PUT,DELETE
	Method string
	// If not prefixed with "/", Credential will prepend the accountId
	// /restapi/v2/accounts/{accountId}
	Path string
	// Payload will be marshalled into the request body
	Payload interface{}
	// Additional query parameters
	QueryOpts url.Values
	// Upload files for document creation
	Files []*UploadFile
	// Set Accept to a mimeType if response will
	// not be application/json
	Accept string
	// Leave nil for v2
	Version *APIVersion
}

Op contains all needed information to perform a DocuSign operation. Used in the sub packages, and may be used for testing or creating new/corrected operations.

func (*Op) Do

func (op *Op) Do(ctx context.Context, result interface{}) error

Do sends a request to DocuSign. Response data is decoded into result. If result is a **Download, do sets the File.ReadCloser to the *http.Response. The developer is responsible for closing the Download.ReadCloser. Any non-2xx status code is returned as a *ResponseError.

type RecipientAttachmentXML

type RecipientAttachmentXML struct {
	Data  string `xml:"Data" json:"data,omitempty"`
	Label string `xml:"Label" json:"label,omitempty"`
}

RecipientAttachmentXML contains a serialized attachement in base64 format.

type RecipientStatusXML

type RecipientStatusXML struct {
	Type                string                 `xml:"Type" json:"type,omitempty"`
	Email               string                 `xml:"Email" json:"email,omitempty"`
	UserName            string                 `xml:"UserName" json:"userName,omitempty"`
	RoutingOrder        string                 `xml:"RoutingOrder" json:"routingOrder,omitempty"`
	Sent                *DSTime                `xml:"Sent" json:"sent,omitempty"`
	Delivered           *DSTime                `xml:"Delivered" json:"delivered,omitempty"`
	Signed              *DSTime                `xml:"Signed" json:"signed,omitempty"`
	DeclineReason       string                 `xml:"DeclineReason" json:"declineReason,omitempty"`
	Status              string                 `xml:"Status" json:"status,omitempty"`
	RecipientIPAddress  string                 `xml:"RecipientIPAddress" json:"recipientIPAdress,omitempty"`
	CustomFields        []CustomFieldXML       `xml:"CustomFields>CustomField" json:"customFields,omitempty"`
	AccountStatus       string                 `xml:"AccountStatus" json:"accountStatus,omitempty"`
	RecipientID         string                 `xml:"RecipientId" json:"recipientId,omitempty"`
	TabStatuses         []TabStatusXML         `xml:"TabStatuses>TabStatus" json:"tabStatuses,omitempty"`
	FormData            []NmValXML             `xml:"FormData>xfdf>fields>field" json:"formData,omitempty"`
	RecipientAttachment RecipientAttachmentXML `xml:"RecipientAttachment>Attachment" json:"recipientAttachment,omitempty"`
}

RecipientStatusXML contains data describing each recipient for an envelope.

type ResponseError

type ResponseError struct {
	ErrorCode   string `json:"errorCode,omitempty"`
	Description string `json:"message,omitempty"`
	Status      int    `json:"-"`
	Raw         []byte `json:"-"`
	OriginalErr error  `json:"-"`
}

ResponseError describes DocuSign's server error response. https://developers.docusign.com/esign-rest-api/guides/status-and-error-codes#general-error-response-handling

func NewResponseError

func NewResponseError(buff []byte, status int) *ResponseError

NewResponseError unmarshals buff, containing a DocuSign server error, into a ResponseError

func (ResponseError) Error

func (r ResponseError) Error() string

Error fulfills error interface

type TabStatusXML

type TabStatusXML struct {
	TabType           string `xml:"TabType" json:"tabType,omitempty"`
	Status            string `xml:"Status" json:"status,omitempty"`
	XPosition         string `xml:"XPosition" json:"xPosition,omitempty"`
	YPosition         string `xml:"YPosition" json:"yPosition,omitempty"`
	TabLabel          string `xml:"TabLabel" json:"tabLabel,omitempty"`
	TabName           string `xml:"TabName" json:"tabName,omitempty"`
	TabValue          string `xml:"TabValue" json:"tabValue,omitempty"`
	DocumentID        string `xml:"DocumentID" json:"documentID,omitempty"`
	PageNumber        string `xml:"PageNumber" json:"pageNumber,omitempty"`
	OriginalValue     string `xml:"OriginalValue" json:"originalValue,omitempty"`
	ValidationPattern string `xml:"ValidationPattern" json:"validationPattern,omitempty"`
	ListValues        string `xml:"ListValues" json:"listValues,omitempty"`
	ListSelectedValue string `xml:"ListSelectedValue" json:"listSelectedValue,omitempty"`
	CustomTabType     string `xml:"CustomTabType" json:"customTabType,omitempty"`
}

TabStatusXML describes the properties of each recipient tab

type UploadFile

type UploadFile struct {
	// mime type of content
	ContentType string
	// file name to display in envelope or to identify signature
	FileName string
	// envelope documentId
	ID string
	// reader for creating file
	io.Reader
}

UploadFile describes an a document attachment for uploading.

func (*UploadFile) Close

func (uf *UploadFile) Close()

Close closes the io.Reader if an io.Closer.

func (*UploadFile) Valid

func (uf *UploadFile) Valid() bool

Valid ensures UploadFile.Reader is not nil.

type UserInfo

type UserInfo struct {
	APIUsername string            `json:"sub"`
	Accounts    []UserInfoAccount `json:"accounts"`
	Name        string            `json:"name"`
	GivenName   string            `json:"given_name"`
	FamilyName  string            `json:"family_name"`
	Email       string            `json:"email"`
}

UserInfo provides all account info for a specific user. Data from the /oauth/userinfo op is unmarshaled into this struct.

type UserInfoAccount

type UserInfoAccount struct {
	AccountID   string `json:"account_id"`
	IsDefault   bool   `json:"is_default"`
	AccountName string `json:"account_name"`
	BaseURI     string `json:"base_uri"`
}

UserInfoAccount contains the account information for a UserInfo

Directories

Path Synopsis
Package click implements DocuSign's click api.
Package click implements DocuSign's click api.
This file provides lists of type overrides for definition properties (struct fields) and for operation parameters found in Docusign's Rest API swagger definition.
This file provides lists of type overrides for definition properties (struct fields) and for operation parameters found in Docusign's Rest API swagger definition.
Package legacy implements the deprecated legacy authentication methods for the version 2 Docusign rest api.
Package legacy implements the deprecated legacy authentication methods for the version 2 Docusign rest api.
v2
accounts
Package accounts implements the DocuSign SDK category Accounts.
Package accounts implements the DocuSign SDK category Accounts.
authentication
Package authentication implements the DocuSign SDK category Authentication.
Package authentication implements the DocuSign SDK category Authentication.
billing
Package billing implements the DocuSign SDK category Billing.
Package billing implements the DocuSign SDK category Billing.
bulkenvelopes
Package bulkenvelopes implements the DocuSign SDK category BulkEnvelopes.
Package bulkenvelopes implements the DocuSign SDK category BulkEnvelopes.
cloudstorage
Package cloudstorage implements the DocuSign SDK category CloudStorage.
Package cloudstorage implements the DocuSign SDK category CloudStorage.
connect
Package connect implements the DocuSign SDK category Connect.
Package connect implements the DocuSign SDK category Connect.
customtabs
Package customtabs implements the DocuSign SDK category CustomTabs.
Package customtabs implements the DocuSign SDK category CustomTabs.
diagnostics
Package diagnostics implements the DocuSign SDK category Diagnostics.
Package diagnostics implements the DocuSign SDK category Diagnostics.
envelopes
Package envelopes implements the DocuSign SDK category Envelopes.
Package envelopes implements the DocuSign SDK category Envelopes.
folders
Package folders implements the DocuSign SDK category Folders.
Package folders implements the DocuSign SDK category Folders.
future
Package future implements the DocuSign SDK category Future.
Package future implements the DocuSign SDK category Future.
model
Package model provides definitions for all input and output parameters types found in DocuSign's OpenAPI (swagger) file.
Package model provides definitions for all input and output parameters types found in DocuSign's OpenAPI (swagger) file.
powerforms
Package powerforms implements the DocuSign SDK category PowerForms.
Package powerforms implements the DocuSign SDK category PowerForms.
signinggroups
Package signinggroups implements the DocuSign SDK category SigningGroups.
Package signinggroups implements the DocuSign SDK category SigningGroups.
templates
Package templates implements the DocuSign SDK category Templates.
Package templates implements the DocuSign SDK category Templates.
uncategorized
Package uncategorized implements the DocuSign SDK category Uncategorized.
Package uncategorized implements the DocuSign SDK category Uncategorized.
usergroups
Package usergroups implements the DocuSign SDK category UserGroups.
Package usergroups implements the DocuSign SDK category UserGroups.
users
Package users implements the DocuSign SDK category Users.
Package users implements the DocuSign SDK category Users.
workspaces
Package workspaces implements the DocuSign SDK category Workspaces.
Package workspaces implements the DocuSign SDK category Workspaces.
v2.1
accounts
Package accounts implements the DocuSign SDK category Accounts.
Package accounts implements the DocuSign SDK category Accounts.
billing
Package billing implements the DocuSign SDK category Billing.
Package billing implements the DocuSign SDK category Billing.
bulkenvelopes
Package bulkenvelopes implements the DocuSign SDK category BulkEnvelopes.
Package bulkenvelopes implements the DocuSign SDK category BulkEnvelopes.
cloudstorage
Package cloudstorage implements the DocuSign SDK category CloudStorage.
Package cloudstorage implements the DocuSign SDK category CloudStorage.
connect
Package connect implements the DocuSign SDK category Connect.
Package connect implements the DocuSign SDK category Connect.
customtabs
Package customtabs implements the DocuSign SDK category CustomTabs.
Package customtabs implements the DocuSign SDK category CustomTabs.
diagnostics
Package diagnostics implements the DocuSign SDK category Diagnostics.
Package diagnostics implements the DocuSign SDK category Diagnostics.
envelopes
Package envelopes implements the DocuSign SDK category Envelopes.
Package envelopes implements the DocuSign SDK category Envelopes.
folders
Package folders implements the DocuSign SDK category Folders.
Package folders implements the DocuSign SDK category Folders.
model
Package model provides definitions for all input and output parameters types found in DocuSign's OpenAPI (swagger) file.
Package model provides definitions for all input and output parameters types found in DocuSign's OpenAPI (swagger) file.
powerforms
Package powerforms implements the DocuSign SDK category PowerForms.
Package powerforms implements the DocuSign SDK category PowerForms.
signinggroups
Package signinggroups implements the DocuSign SDK category SigningGroups.
Package signinggroups implements the DocuSign SDK category SigningGroups.
templates
Package templates implements the DocuSign SDK category Templates.
Package templates implements the DocuSign SDK category Templates.
uncategorized
Package uncategorized implements the DocuSign SDK category Uncategorized.
Package uncategorized implements the DocuSign SDK category Uncategorized.
usergroups
Package usergroups implements the DocuSign SDK category UserGroups.
Package usergroups implements the DocuSign SDK category UserGroups.
users
Package users implements the DocuSign SDK category Users.
Package users implements the DocuSign SDK category Users.
workspaces
Package workspaces implements the DocuSign SDK category Workspaces.
Package workspaces implements the DocuSign SDK category Workspaces.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL