|
1 | 1 | # ipdata |
2 | | -[](https://github.com/theckman/go-ipdata/blob/master/LICENSE) |
3 | | -[](https://godoc.org/github.com/theckman/go-ipdata) |
4 | | -[](https://github.com/theckman/go-ipdata/releases) |
5 | | -[](https://travis-ci.org/theckman/go-ipdata/branches) |
6 | | -[](https://gocover.io/github.com/theckman/go-ipdata) |
7 | | -[](https://goreportcard.com/report/github.com/theckman/go-ipdata) |
| 2 | +[](https://github.com/ipdata/go/actions/workflows/ci.yml) |
| 3 | +[](https://pkg.go.dev/github.com/ipdata/go) |
| 4 | +[](https://github.com/ipdata/go/blob/master/LICENSE) |
| 5 | +[](https://github.com/ipdata/go/releases) |
| 6 | +[](https://goreportcard.com/report/github.com/ipdata/go) |
8 | 7 |
|
9 | | -Package ipdata is a client for the https://ipdata.co API. It provides functions |
10 | | -for looking up data, as well as parsing the data in a programmatic way. The |
11 | | -simplest usage is to build a new client and then use the `Lookup` method. |
| 8 | +Package ipdata is a Go client for the [ipdata.co](https://ipdata.co) API. It |
| 9 | +provides IP geolocation, threat intelligence, company detection, currency, |
| 10 | +timezone, carrier, and language data for any IP address. |
| 11 | + |
| 12 | +## Installation |
| 13 | + |
| 14 | +``` |
| 15 | +go get github.com/ipdata/go |
| 16 | +``` |
12 | 17 |
|
13 | 18 | ## License |
14 | 19 | This code is released under the MIT License. Please see the |
15 | | -[LICENSE](https://github.com/theckman/go-ipdata/blob/master/LICENSE) for the |
| 20 | +[LICENSE](https://github.com/ipdata/go/blob/master/LICENSE) for the |
16 | 21 | full content of the license. |
17 | 22 |
|
18 | | -## Contributing |
19 | | -If you'd like to contribute to this project, I welcome any pull requests against |
20 | | -this repo. The only ask is that a GitHub issue be opened detailing the desired |
21 | | -functionality before making any pull requests. |
22 | | - |
23 | 23 | ## Usage |
24 | | -The service provided by `ipdata` requires an API key before making API calls. |
25 | | -Attempts to create a client without one will fail, as would attempts to contact |
26 | | -the API. You can get an API key from https://ipdata.co/. |
27 | 24 |
|
28 | | -Here is a simple example of using the library: |
| 25 | +The service provided by ipdata requires an API key. You can get one from |
| 26 | +https://ipdata.co/. |
| 27 | + |
| 28 | +### Basic Lookup |
| 29 | + |
| 30 | +```go |
| 31 | +package main |
29 | 32 |
|
30 | | -```Go |
31 | 33 | import ( |
32 | | - "github.com/ipdata/go" |
33 | | - "fmt" |
| 34 | + "fmt" |
| 35 | + |
| 36 | + "github.com/ipdata/go" |
34 | 37 | ) |
35 | 38 |
|
36 | | -ipd, _ := ipdata.NewClient("EXAMPLE_API_KEY") |
| 39 | +func main() { |
| 40 | + client, err := ipdata.NewClient("YOUR_API_KEY") |
| 41 | + if err != nil { |
| 42 | + panic(err) |
| 43 | + } |
| 44 | + |
| 45 | + data, err := client.Lookup("8.8.8.8") |
| 46 | + if err != nil { |
| 47 | + panic(err) |
| 48 | + } |
| 49 | + |
| 50 | + fmt.Printf("IP: %s\n", data.IP) |
| 51 | + fmt.Printf("Country: %s (%s)\n", data.CountryName, data.CountryCode) |
| 52 | + fmt.Printf("City: %s\n", data.City) |
| 53 | + fmt.Printf("ASN: %s (%s)\n", data.ASN.ASN, data.ASN.Name) |
| 54 | + |
| 55 | + if data.Company != nil { |
| 56 | + fmt.Printf("Company: %s\n", data.Company.Name) |
| 57 | + } |
| 58 | + |
| 59 | + if data.Threat != nil { |
| 60 | + fmt.Printf("VPN: %v, Tor: %v, Proxy: %v\n", |
| 61 | + data.Threat.IsVPN, data.Threat.IsTOR, data.Threat.IsProxy) |
| 62 | + } |
| 63 | +} |
| 64 | +``` |
| 65 | + |
| 66 | +### EU Endpoint (GDPR Compliance) |
| 67 | + |
| 68 | +For GDPR compliance, use `NewEUClient` to route all requests through EU data |
| 69 | +centers only (Frankfurt, Paris, and Ireland): |
| 70 | + |
| 71 | +```go |
| 72 | +client, err := ipdata.NewEUClient("YOUR_API_KEY") |
| 73 | +``` |
| 74 | + |
| 75 | +### Field Filtering |
| 76 | + |
| 77 | +Request only specific fields to reduce response size: |
37 | 78 |
|
38 | | -data, err := ipd.Lookup("8.8.8.8") |
| 79 | +```go |
| 80 | +data, err := client.LookupFields("8.8.8.8", []string{"ip", "country_name", "threat"}) |
39 | 81 | if err != nil { |
40 | | - // handle error |
| 82 | + panic(err) |
41 | 83 | } |
42 | 84 |
|
43 | | -fmt.Printf("%s (%s)\n", data.IP, data.ASN) |
| 85 | +fmt.Printf("%s - %s\n", data.IP, data.CountryName) |
44 | 86 | ``` |
45 | 87 |
|
46 | | -Errors returned from the lookup function calls may be of type `Error`, which |
47 | | -includes the message from the API and the HTTP status code. The `Error()` method |
48 | | -on this type only returns the message and not the status code. To maintain |
49 | | -compatibility with Go 1.12.x, this is still using github.com/pkg/errors for |
50 | | -error management: |
| 88 | +### Bulk Lookup |
51 | 89 |
|
52 | | -```Go |
| 90 | +Look up multiple IPs in a single request: |
| 91 | + |
| 92 | +```go |
| 93 | +results, err := client.BulkLookup([]string{"8.8.8.8", "1.1.1.1"}) |
| 94 | +if err != nil { |
| 95 | + // err may be of type ipdata.Error with index of first failure |
| 96 | + // results may still contain partial data |
| 97 | +} |
| 98 | + |
| 99 | +for _, ip := range results { |
| 100 | + if ip != nil { |
| 101 | + fmt.Printf("%s: %s\n", ip.IP, ip.CountryName) |
| 102 | + } |
| 103 | +} |
| 104 | +``` |
| 105 | + |
| 106 | +### Error Handling |
| 107 | + |
| 108 | +Errors returned from lookup functions may be of type `Error`, which includes |
| 109 | +the message from the API and the HTTP status code: |
| 110 | + |
| 111 | +```go |
53 | 112 | import "github.com/pkg/errors" |
54 | 113 |
|
55 | | -data, err := ipd.Lookup("8.8.8.8") |
| 114 | +data, err := client.Lookup("8.8.8.8") |
56 | 115 | if err != nil { |
57 | | - // do a type assertion on the error |
58 | | - rerr, ok := errors.Cause(err).(ipdata.Error) |
59 | | - |
60 | | - if !ok { |
61 | | - // this wasn't a failure from rate limiting |
62 | | - } |
63 | | - |
64 | | - fmt.Println("%d: %s", rerr.Code(), rerr.Error()) |
| 116 | + if apiErr, ok := errors.Cause(err).(ipdata.Error); ok { |
| 117 | + fmt.Printf("API error %d: %s\n", apiErr.Code(), apiErr.Error()) |
| 118 | + } |
65 | 119 | } |
66 | 120 | ``` |
67 | 121 |
|
| 122 | +## Response Fields |
| 123 | + |
| 124 | +The `IP` struct includes all fields from the ipdata API response: |
| 125 | + |
| 126 | +| Field | Type | Description | |
| 127 | +|-------|------|-------------| |
| 128 | +| `IP` | `string` | IP address | |
| 129 | +| `City` | `string` | City name | |
| 130 | +| `Region` | `string` | Region/state name | |
| 131 | +| `RegionCode` | `string` | ISO 3166-2 region code | |
| 132 | +| `CountryName` | `string` | Country name | |
| 133 | +| `CountryCode` | `string` | ISO 3166-1 alpha-2 code | |
| 134 | +| `ContinentName` | `string` | Continent name | |
| 135 | +| `ContinentCode` | `string` | 2-letter continent code | |
| 136 | +| `Latitude` | `float64` | Geographic latitude | |
| 137 | +| `Longitude` | `float64` | Geographic longitude | |
| 138 | +| `Postal` | `string` | Postal/zip code | |
| 139 | +| `CallingCode` | `string` | International calling code | |
| 140 | +| `Flag` | `string` | URL to country flag image | |
| 141 | +| `EmojiFlag` | `string` | Flag emoji character | |
| 142 | +| `EmojiUnicode` | `string` | Unicode representation | |
| 143 | +| `IsEU` | `bool` | Whether in the EU | |
| 144 | +| `Organization` | `string` | Organization name | |
| 145 | +| `ASN` | `ASN` | Autonomous System Number data | |
| 146 | +| `Company` | `*Company` | Company/organization data | |
| 147 | +| `Carrier` | `*Carrier` | Mobile carrier data | |
| 148 | +| `Languages` | `[]Language` | Languages spoken | |
| 149 | +| `Currency` | `*Currency` | Local currency info | |
| 150 | +| `TimeZone` | `*TimeZone` | Timezone info | |
| 151 | +| `Threat` | `*Threat` | Threat intelligence data | |
| 152 | +| `Count` | `string` | API request count (24h) | |
| 153 | +| `Status` | `int` | HTTP status code | |
| 154 | + |
| 155 | +### Nested Types |
| 156 | + |
| 157 | +**`Company`**: `Name`, `Domain`, `Network`, `Type` |
| 158 | + |
| 159 | +**`ASN`**: `ASN`, `Name`, `Domain`, `Route`, `Type` |
| 160 | + |
| 161 | +**`Carrier`**: `Name`, `MCC`, `MNC` |
| 162 | + |
| 163 | +**`Language`**: `Name`, `Native`, `Code` |
| 164 | + |
| 165 | +**`Currency`**: `Name`, `Code`, `Symbol`, `Native`, `Plural` |
| 166 | + |
| 167 | +**`TimeZone`**: `Name`, `Abbreviation`, `Offset`, `IsDST`, `CurrentTime` |
| 168 | + |
| 169 | +**`Threat`**: `IsTOR`, `IsVPN`, `IsICloudRelay`, `IsProxy`, `IsDatacenter`, `IsAnonymous`, `IsKnownAttacker`, `IsKnownAbuser`, `IsThreat`, `IsBogon`, `Blocklists`, `Scores` |
| 170 | + |
68 | 171 | ## Contributors |
69 | 172 |
|
70 | 173 | - [Tim Heckman](https://github.com/theckman/) - Created the first version of this library |
0 commit comments