forked from rapidpro/mailroom
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
services/external/weni/sentenx: integration client
- Loading branch information
Showing
2 changed files
with
137 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package sentenx | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
"strings" | ||
|
||
"github.com/nyaruka/gocommon/httpx" | ||
"github.com/nyaruka/gocommon/jsonx" | ||
"github.com/pkg/errors" | ||
) | ||
|
||
const BaseURL = "https://sentenx.weni.ai" | ||
|
||
type SearchRequest struct { | ||
Search string `json:"search,omitempty"` | ||
Filter struct { | ||
CatalogID string `json:"catalog_id,omitempty"` | ||
} `json:"filter,omitempty"` | ||
Threshold float64 `json:"threshold,omitempty"` | ||
} | ||
|
||
type SearchResponse struct { | ||
Products []Product `json:"products,omitempty"` | ||
} | ||
|
||
type Product struct { | ||
ProductRetailerID string `json:"product_retailer_id,omitempty"` | ||
} | ||
|
||
type ErrorResponse struct { | ||
Detail []struct { | ||
Msg string `json:"msg,omitempty"` | ||
} `json:"detail,omitempty"` | ||
} | ||
|
||
type Client struct { | ||
httpClient *http.Client | ||
httpRetries *httpx.RetryConfig | ||
baseURL string | ||
} | ||
|
||
func NewClient(httpClient *http.Client, httpRetries *httpx.RetryConfig, baseURL string) *Client { | ||
return &Client{httpClient, httpRetries, baseURL} | ||
} | ||
|
||
func (c *Client) Request(method, url string, body, response interface{}) (*httpx.Trace, error) { | ||
b, err := json.Marshal(body) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
data := strings.NewReader(string(b)) | ||
req, err := httpx.NewRequest(method, url, data, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
trace, err := httpx.DoTrace(c.httpClient, req, c.httpRetries, nil, -1) | ||
if err != nil { | ||
return trace, err | ||
} | ||
|
||
if trace.Response.StatusCode >= 400 { | ||
var errorResponse []ErrorResponse | ||
err = jsonx.Unmarshal(trace.ResponseBody, &errorResponse) | ||
if err != nil { | ||
return trace, err | ||
} | ||
return trace, errors.New(fmt.Sprint(errorResponse)) | ||
} | ||
|
||
if response != nil { | ||
err := json.Unmarshal(trace.ResponseBody, response) | ||
return trace, errors.Wrap(err, "couldn't unmarshal response body") | ||
} | ||
return trace, nil | ||
} | ||
|
||
func (c *Client) Search(data *SearchRequest) (*SearchResponse, *httpx.Trace, error) { | ||
requestURL := c.baseURL + "/search" | ||
response := &SearchResponse{} | ||
|
||
trace, err := c.Request("GET", requestURL, data, response) | ||
if err != nil { | ||
return nil, trace, err | ||
} | ||
return response, trace, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package sentenx_test | ||
|
||
import ( | ||
"net/http" | ||
"testing" | ||
|
||
"github.com/nyaruka/gocommon/httpx" | ||
"github.com/nyaruka/mailroom/services/external/weni/sentenx" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
const ( | ||
baseURL = "https://sentenx.weni.ai" | ||
) | ||
|
||
func TestRequest(t *testing.T) { | ||
client := sentenx.NewClient(http.DefaultClient, nil, baseURL) | ||
|
||
_, err := client.Request("POST", "", func() {}, nil) | ||
assert.Error(t, err) | ||
|
||
_, err = client.Request("{[:INVALID:]}", "", nil, nil) | ||
assert.Error(t, err) | ||
|
||
defer httpx.SetRequestor(httpx.DefaultRequestor) | ||
httpx.SetRequestor(httpx.NewMockRequestor(map[string][]httpx.MockResponse{ | ||
baseURL: { | ||
httpx.NewMockResponse(400, nil, `[]`), | ||
httpx.NewMockResponse(200, nil, `{}`), | ||
httpx.NewMockResponse(400, nil, `{ | ||
"detail": [ | ||
{ "msg": "dummy error message"} | ||
] | ||
}`), | ||
}, | ||
})) | ||
|
||
_, err = client.Request("GET", baseURL, nil, nil) | ||
assert.Error(t, err) | ||
|
||
_, err = client.Request("GET", baseURL, nil, nil) | ||
assert.Nil(t, err) | ||
|
||
response := new(interface{}) | ||
_, err = client.Request("GET", baseURL, nil, response) | ||
assert.Error(t, err) | ||
} |