OneSpan Sign How To: Create and Send A Package with REST in Go

Haris Haidary,

Go (or golang) is an open-source general purpose programming language created by Google. Go's native concurrency features are well suited for web applications (e.g. APIs, Web servers, etc.). Go offers many advantages over other general-purpose programming languages. For one, the executable files created by Go are stand-alone executables with no external dependencies. Another advantage Go has is speed. The resulting executables run faster than most dynamically executed languages. Finally, Go programs can also talk to external C libraries, which gives you more flexibility in what you can achieve. In this blog, I will show you how to create and send a package with the REST API in Go.

The Code

If you don’t already have Go installed, you can download it from the official website, here. The complete example code is available on our Developer Community Code Share. Let's get started. In your favorite text editor, create a new file named "CreateAndSendPackage.go" and save it in a location of your choice. You can go ahead and copy the code below. I will go over it in more detail further down.

package main

import (
  "bytes"
  "fmt"
  "io"
  "log"
  "mime/multipart"
  "net/http"
  "os"
  "path/filepath"
)

func main() {

  
  json := `{"documents":[{"approvals":[{"id":"ExampleSignatureId","role":"Signer1","fields":[{"page":0,"top":200,"subtype":"LABEL","height":50,"left":100,"width":200,"id":"myLabelField","type":"INPUT","value":"Example label field value"},{"page":0,"top":100,"subtype":"FULLNAME","height":50,"left":100,"width":200,"type":"SIGNATURE","name":"ExampleSignatureId"}],"name":""}],"id":"sample-contract","name":"Test Document"}],"status":"DRAFT","type":"PACKAGE","roles":[{"id":"Signer1","type":"SIGNER","signers":[{"email":"[email protected]","firstName":"John","lastName":"Smith","id":"Signer1"}],"name":"Signer1"}],"name":"Example Package in GO"}`

  extraParam := map[string]string{
      "payload": json,
  }
  
  doc_path, _ := os.Getwd()
  doc_path += "/sample_contract2.pdf"

  file, err := os.Open(doc_path)
  if err != nil {
      log.Fatal(err)
  }
  defer file.Close()

  body := &bytes.Buffer{}
  writer := multipart.NewWriter(body)
  part, err := writer.CreateFormFile("file", filepath.Base(doc_path))
  if err != nil {
      log.Fatal(err)
  }
  _, err = io.Copy(part, file)

  for key, val := range extraParam {
      _ = writer.WriteField(key, val)
  }
  err = writer.Close()
  if err != nil {
      log.Fatal(err)
  }

  req, err := http.NewRequest("POST", "https://sandbox.esignlive.com/api/packages", body)
  req.Header.Set("Authorization", "Basic your_api_key")
  req.Header.Set("Accept", "application/json")
  req.Header.Set("Content-Type", writer.FormDataContentType())

  if err != nil {
      log.Fatal(err)
  }
  client := &http.Client{}
  resp, err := client.Do(req)
  if err != nil {
      log.Fatal(err)
  } else {
      body := &bytes.Buffer{}
      _, err := body.ReadFrom(resp.Body)
    if err != nil {
          log.Fatal(err)
      }
    resp.Body.Close()
      fmt.Println(resp.StatusCode)
      fmt.Println(resp.Header)
      fmt.Println(body)
  }
}

Now, let’s go over the code in greater detail. The first couple of lines imports the modules needed in order to make HTTP requests to OneSpan Sign's API.

import (
  "bytes"
  "fmt"
  "io"
  "log"
  "mime/multipart"
  "net/http"
  "os"
  "path/filepath"
)

Next, we define the json payload that will be included in the POST request to OneSpan Sign. You would typically build your json string dynamically versus having a big string like in this example. I chose to do so for simplicity.

json := `{"documents":[{"approvals":[{"id":"ExampleSignatureId","role":"Signer1","fields":[{"page":0,"top":200,"subtype":"LABEL","height":50,"left":100,"width":200,"id":"myLabelField","type":"INPUT","value":"Example label field value"},{"page":0,"top":100,"subtype":"FULLNAME","height":50,"left":100,"width":200,"type":"SIGNATURE","name":"ExampleSignatureId"}],"name":""}],"id":"sample-contract","name":"Test Document"}],"status":"DRAFT","type":"PACKAGE","roles":[{"id":"Signer1","type":"SIGNER","signers":[{"email":"[email protected]","firstName":"John","lastName":"Smith","id":"Signer1"}],"name":"Signer1"}],"name":"Example Package in GO"}`

extraParam := map[string]string{
      "payload": json,
}

The next couple of lines is where the pdf document is opened and read. Make sure to use the "defer" call to ensure that the pdf document is closed at the end of the program. Otherwise, an error will be thrown.

doc_path, _ := os.Getwd()
doc_path += "/sample_contract2.pdf"

file, err := os.Open(doc_path)
if err != nil {
    log.Fatal(err)
}
defer file.Close()

Once you've defined the json payload and the document, the next step is to build the multipart/form-data request using the multipart module, as shown below.

body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile("file", filepath.Base(doc_path))
if err != nil {
    log.Fatal(err)
}
_, err = io.Copy(part, file)

for key, val := range extraParam {
    _ = writer.WriteField(key, val)
}
err = writer.Close()
if err != nil {
    log.Fatal(err)
}

Then, you add the appropriate headers required to make HTTP requests to OneSpan Sign's API.

req, err := http.NewRequest("POST", "https://sandbox.esignlive.com/api/packages", body)
req.Header.Set("Authorization", "Basic your_api_key")
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", writer.FormDataContentType())

if err != nil {
    log.Fatal(err)
}

Finally, you build your HTTP client and make your POST request. Optionally, you can also print the response sent by OneSpan Sign.

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
    log.Fatal(err)
} else {
    body := &bytes.Buffer{}
    _, err := body.ReadFrom(resp.Body)
    if err != nil {
        log.Fatal(err)
    }
    resp.Body.Close()
    fmt.Println(resp.StatusCode)
    fmt.Println(resp.Header)
    fmt.Println(body)
}

Running Your Code

Open your command prompt and change the current directory to the location where you saved your "CreateAndSendPackage.go" file. Then, enter the following lines:

go build CreateAndSendPackage.go
CreateAndSendPackage.exe

OneSpan Sign will then return a package id as a response, which will be printed to the command prompt window. Capture

If you have questions regarding this blog or anything else concerning integrating OneSpan Sign into your application, visit the developer community forums: https://developer.OneSpan.com. That's it from me. Thank you for reading! If you found this post helpful, please share it on Facebook, Twitter, or LinkedIn.

 Haris Haidary Junior Technical Evangelist LinkedIn | Twitter