github.com/wit-ai/wit-go/v2@v2.0.2/witai.go (about)

     1  // Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
     2  
     3  package witai
     4  
     5  import (
     6  	"encoding/json"
     7  	"fmt"
     8  	"io"
     9  	"net/http"
    10  	"time"
    11  )
    12  
    13  const (
    14  	// DefaultVersion - https://wit.ai/docs/http/20200513/
    15  	DefaultVersion = "20200513"
    16  	// WitTimeFormat - the custom format of the timestamp sent by the api
    17  	WitTimeFormat = "2006-01-02T15:04:05Z0700"
    18  )
    19  
    20  // Client - Wit.ai client type
    21  type Client struct {
    22  	APIBase      string
    23  	Token        string
    24  	Version      string
    25  	headerAuth   string
    26  	headerAccept string
    27  	httpClient   *http.Client
    28  }
    29  
    30  type errorResp struct {
    31  	Body  string `json:"body"`
    32  	Error string `json:"error"`
    33  }
    34  
    35  // NewClient - returns Wit.ai client for default API version
    36  func NewClient(token string) *Client {
    37  	return newClientWithVersion(token, DefaultVersion)
    38  }
    39  
    40  func newClientWithVersion(token, version string) *Client {
    41  	headerAuth := fmt.Sprintf("Bearer %s", token)
    42  	headerAccept := fmt.Sprintf("application/vnd.wit.%s+json", version)
    43  
    44  	defaultClient := &http.Client{
    45  		Timeout: time.Second * 10,
    46  	}
    47  
    48  	return &Client{
    49  		APIBase:      "https://api.wit.ai",
    50  		Token:        token,
    51  		Version:      version,
    52  		headerAuth:   headerAuth,
    53  		headerAccept: headerAccept,
    54  		httpClient:   defaultClient,
    55  	}
    56  }
    57  
    58  // SetHTTPClient allows to use your custom http.Client
    59  func (c *Client) SetHTTPClient(httpClient *http.Client) {
    60  	c.httpClient = httpClient
    61  }
    62  
    63  func (c *Client) request(method, url string, ct string, body io.Reader) (io.ReadCloser, error) {
    64  	req, err := http.NewRequest(method, c.APIBase+url, body)
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  
    69  	req.Header.Set("Authorization", c.headerAuth)
    70  	req.Header.Set("Accept", c.headerAccept)
    71  	req.Header.Set("Content-Type", ct)
    72  
    73  	resp, err := c.httpClient.Do(req)
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  
    78  	if resp.StatusCode >= http.StatusBadRequest {
    79  		defer resp.Body.Close()
    80  
    81  		var e *errorResp
    82  		decoder := json.NewDecoder(resp.Body)
    83  		err = decoder.Decode(&e)
    84  		if err != nil {
    85  			return nil, fmt.Errorf("unable to decode error message: %s", err.Error())
    86  		}
    87  
    88  		// Wit.ai errors sometimes have "error", sometimes "body" message
    89  		if len(e.Error) > 0 {
    90  			return nil, fmt.Errorf("unable to make a request. error: %s", e.Error)
    91  		}
    92  
    93  		if len(e.Body) > 0 {
    94  			return nil, fmt.Errorf("unable to make a request. error: %s", e.Body)
    95  		}
    96  
    97  		return nil, fmt.Errorf("unable to make a request. error: %v", e)
    98  	}
    99  
   100  	return resp.Body, nil
   101  }