-
Notifications
You must be signed in to change notification settings - Fork 0
/
client.go
151 lines (127 loc) · 4.38 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package numverify
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"strings"
"time"
hum "github.com/grokify/simplego/net/httputilmore"
"github.com/grokify/simplego/net/urlutil"
)
const (
CountriesEndpoint = "http://apilayer.net/api/countries"
ValidateEndpoint = "http://apilayer.net/api/validate"
)
var EnvNumverifyAccessKey = "NUMVERIFY_ACCESS_KEY"
type Client struct {
AccessKey string
}
func NewClient(accessKey string) Client {
return Client{AccessKey: strings.TrimSpace(accessKey)}
}
// Returns separate objects for API Success and API Error structs because
// Numverify API will return a 200 OK for errors such as auth errors.
func (nc *Client) Validate(params Params) (*Response, *http.Response, error) {
params.AccessKey = strings.TrimSpace(params.AccessKey)
if len(params.AccessKey) == 0 {
params.AccessKey = nc.AccessKey
}
apiURL, err := urlutil.URLAddQueryString(ValidateEndpoint, params.MapStringSlice())
if err != nil {
return nil, nil, err
}
resp, respBody, err := hum.GetResponseAndBytes(apiURL.String())
nvResp := Response{
StatusCode: resp.StatusCode,
ClientErr: err,
Body: string(respBody),
Time: time.Now()}
if err != nil {
return &nvResp, resp, err
} else if resp.StatusCode >= 300 {
return &nvResp, resp, fmt.Errorf("Numverify API Error: %v", resp.StatusCode)
}
// Try both success and response. Will
// error for one.
var apiSuccessInfo ResponseSuccess
var apiErrorInfo ResponseError
err = json.Unmarshal(respBody, &apiSuccessInfo)
if err != nil {
err = json.Unmarshal(respBody, &apiErrorInfo)
}
nvResp.Success = &apiSuccessInfo
nvResp.Failure = &apiErrorInfo
return &nvResp, resp, err
//return &apiSuccessInfo, &apiErrorInfo, resp, err
}
// Countries returns separate objects for API Success and API Error structs because
// Numverify API will return a 200 OK for errors such as auth errors.
func (nc *Client) Countries() (map[string]Country, *ResponseError, *http.Response, error) {
apiURL := CountriesEndpoint + "?access_key=" + nc.AccessKey
resp, respBody, err := hum.GetResponseAndBytes(apiURL)
countries := map[string]Country{}
if err != nil {
return countries, nil, resp, err
} else if resp.StatusCode >= 300 {
return countries, nil, resp, fmt.Errorf("Numverify API Error: %v", resp.StatusCode)
}
err = json.Unmarshal(respBody, &countries)
if err != nil {
return countries, nil, resp, err
}
var apiErrorInfo ResponseError
err = json.Unmarshal(respBody, &apiErrorInfo)
return countries, &apiErrorInfo, resp, err
}
// Params is the request query parameters for the
// API. AccessKey is added by the client and is not needed
// per-request.
type Params struct {
AccessKey string `url:"access_key" json:"access_key,omitempty"`
Number string `url:"number" json:"number,omitempty"`
CountryCode string `url:"country_code" json:"country_code,omitempty"`
Format int `url:"format" json:"format,omitempty"`
Callback string `url:"callback" json:"callback,omitempty"`
}
func (params *Params) MapStringSlice() map[string][]string {
return map[string][]string{
"access_key": []string{params.AccessKey},
"number": []string{params.Number},
"country_code": []string{params.CountryCode},
"format": []string{strconv.Itoa(params.Format)},
"callback": []string{params.Callback}}
}
type ResponseSuccess struct {
Valid bool `json:"valid,omitempty"`
Number string `json:"number,omitempty"`
LocalFormat string `json:"local_format,omitempty"`
InternationalFormat string `json:"international_format,omitempty"`
CountryPrefix string `json:"country_prefix,omitempty"`
CountryCode string `json:"country_code,omitempty"`
CountryName string `json:"country_name,omitempty"`
Location string `json:"location,omitempty"`
Carrier string `json:"carrier,omitempty"`
LineType string `json:"line_type,omitempty"`
}
type ResponseError struct {
Success bool `json:"success"`
Error Error `json:"error,omitempty"`
}
type Error struct {
Code int `json:"code,omitempty"`
Type string `json:"type,omitempty"`
Info string `json:"info,omitempty"`
}
type Country struct {
CountryName string `json:"country_name,omitempty"`
DialingCode string `json:"dialling_code,omitempty"`
}
type Response struct {
StatusCode int
Body string
ClientErr error
Success *ResponseSuccess
Failure *ResponseError
Time time.Time
}