Skip to content

Commit 7a94016

Browse files
committed
#minor: move to ipbase.com api
1 parent b03a325 commit 7a94016

File tree

7 files changed

+174
-80
lines changed

7 files changed

+174
-80
lines changed

.github/workflows/tag.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
with:
2424
go-version: ${{ steps.vars.outputs.go_version }}
2525
- name: Bump version and push tag
26-
uses: anothrNick/github-tag-action@1.26.0
26+
uses: anothrNick/github-tag-action@1.39.0
2727
id: tagging
2828
env:
2929
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/test.yaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ jobs:
1111
steps:
1212
- name: Install Go
1313
uses: actions/setup-go@v2
14-
with:
15-
go-version: '^1.17.0'
1614
- name: Checkout code
1715
uses: actions/checkout@v2
1816
- name: Test
@@ -23,7 +21,5 @@ jobs:
2321
- uses: actions/checkout@v2
2422
- name: Install Go
2523
uses: actions/setup-go@v2
26-
with:
27-
go-version: '^1.17.0'
2824
- name: golangci-lint
2925
uses: golangci/golangci-lint-action@v2

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
[![PkgGoDev](https://pkg.go.dev/badge/github.com/circa10a/go-geofence)](https://pkg.go.dev/github.com/circa10a/go-geofence?tab=overview)
55
[![Go Report Card](https://goreportcard.com/badge/github.com/circa10a/go-geofence)](https://goreportcard.com/report/github.com/circa10a/go-geofence)
66

7-
A small library to detect if an IP address is close to yours or another of your choosing using https://freegeoip.app/
7+
A small library to detect if an IP address is close to yours or another of your choosing using https://ipbase.com/
88

99
## Usage
1010

11-
First you will need a free API Token from [freegeoip.app](https://freegeoip.app/)
11+
First you will need a free API Token from [ipbase.com](https://ipbase.com/)
1212

1313
```bash
1414
go get github.com/circa10a/go-geofence
@@ -29,8 +29,8 @@ func main() {
2929
geofence, err := geofence.New(&geofence.Config{
3030
// Empty string to geofence your current public IP address, or you can monitor a remote address by supplying it as the first parameter
3131
IPAddress: "",
32-
// freegeoip.app API token
33-
Token: "YOUR_FREEGEOIP_API_TOKEN",
32+
// ipbase.com API token
33+
Token: "YOUR_IPBASE_API_TOKEN",
3434
// Maximum radius of the geofence in kilometers, only clients less than or equal to this distance will return true with isAddressNearby
3535
// 1 kilometer
3636
Radius: 1.0,

geofence.go

Lines changed: 110 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
)
1212

1313
const (
14-
freeGeoIPBaseURL = "https://api.freegeoip.app/json"
14+
ipBaseBaseURL = "https://api.ipbase.com/v2"
1515
deleteExpiredCacheItemsInternal = 10 * time.Minute
1616
)
1717

@@ -24,36 +24,105 @@ type Config struct {
2424
CacheTTL time.Duration
2525
}
2626

27-
// Geofence holds a freegeoip.app client, cache and user supplied config
27+
// Geofence holds a ipbase.com client, cache and user supplied config
2828
type Geofence struct {
29-
Cache *cache.Cache
30-
FreeGeoIPClient *resty.Client
29+
Cache *cache.Cache
30+
IPBaseClient *resty.Client
3131
Config
3232
Latitude float64
3333
Longitude float64
3434
}
3535

36-
// FreeGeoIPResponse is the json response from freegeoip.app
37-
type FreeGeoIPResponse struct {
38-
IP string `json:"ip"`
39-
CountryCode string `json:"country_code"`
40-
CountryName string `json:"country_name"`
41-
RegionCode string `json:"region_code"`
42-
RegionName string `json:"region_name"`
43-
City string `json:"city"`
44-
ZipCode string `json:"zip_code"`
45-
TimeZone string `json:"time_zone"`
46-
Latitude float64 `json:"latitude"`
47-
Longitude float64 `json:"longitude"`
48-
MetroCode int `json:"metro_code"`
36+
// ipBaseResponse is the json response from ipbase.com
37+
type ipBaseResponse struct {
38+
Data data `json:"data"`
4939
}
5040

51-
// FreeGeoIPError is the json response when there is an error from freegeoip.app
52-
type FreeGeoIPError struct {
41+
type timezone struct {
42+
Id string `json:"id"`
43+
CurrentTime string `json:"current_time"`
44+
Code string `json:"code"`
45+
IDaylightSaving bool `json:"is_daylight_saving"`
46+
GmtOffset int `json:"gmt_offset"`
47+
}
48+
49+
type connection struct {
50+
Organization string `json:"organization"`
51+
Isp string `json:"isp"`
52+
Asn int `json:"asn"`
53+
}
54+
55+
type continent struct {
56+
Code string `json:"code"`
57+
Name string `json:"name"`
58+
NameTranslated string `json:"name_translated"`
59+
}
60+
61+
type currencies struct {
62+
Symbol string `json:"symbol"`
63+
Name string `json:"name"`
64+
SymbolNative string `json:"symbol_native"`
65+
Code string `json:"code"`
66+
NamePlural string `json:"name_plural"`
67+
DecimalDigits int `json:"decimal_digits"`
68+
Rounding int `json:"rounding"`
69+
}
70+
71+
type languages struct {
72+
Name string `json:"name"`
73+
NameNative string `json:"name_native"`
74+
}
75+
type country struct {
76+
Alpha2 string `json:"alpha2"`
77+
Alpha3 string `json:"alpha3"`
78+
CallingCodes []string `json:"calling_codes"`
79+
Currencies []currencies `json:"currencies"`
80+
Emoji string `json:"emoji"`
81+
Ioc string `json:"ioc"`
82+
Languages []languages `json:"languages"`
83+
Name string `json:"name"`
84+
NameTranslated string `json:"name_translated"`
85+
Timezones []string `json:"timezones"`
86+
IsInEuropeanUnion bool `json:"is_in_european_union"`
87+
}
88+
89+
type city struct {
90+
Name string `json:"name"`
91+
NameTranslated string `json:"name_translated"`
92+
}
93+
94+
type region struct {
95+
Fips interface{} `json:"fips"`
96+
Alpha2 interface{} `json:"alpha2"`
97+
Name string `json:"name"`
98+
NameTranslated string `json:"name_translated"`
99+
}
100+
101+
type location struct {
102+
GeonamesID interface{} `json:"geonames_id"`
103+
Region region `json:"region"`
104+
Continent continent `json:"continent"`
105+
City city `json:"city"`
106+
Zip string `json:"zip"`
107+
Country country `json:"country"`
108+
Latitude float64 `json:"latitude"`
109+
Longitude float64 `json:"longitude"`
110+
}
111+
112+
type data struct {
113+
Timezone timezone `json:"timezone"`
114+
IP string `json:"ip"`
115+
Type string `json:"type"`
116+
Connection connection `json:"connection"`
117+
Location location `json:"location"`
118+
}
119+
120+
// IPBaseError is the json response when there is an error from ipbase.com
121+
type IPBaseError struct {
53122
Message string `json:"message"`
54123
}
55124

56-
func (e *FreeGeoIPError) Error() string {
125+
func (e *IPBaseError) Error() string {
57126
return e.Message
58127
}
59128

@@ -68,41 +137,42 @@ func validateIPAddress(ipAddress string) error {
68137
return nil
69138
}
70139

71-
// getIPGeoData fetches geolocation data for specified IP address from https://freegeoip.app
72-
func (g *Geofence) getIPGeoData(ipAddress string) (*FreeGeoIPResponse, error) {
73-
freeGeoIPResponse := &FreeGeoIPResponse{}
74-
freeGeoIPError := &FreeGeoIPError{}
140+
// getIPGeoData fetches geolocation data for specified IP address from https://ipbase.com
141+
func (g *Geofence) getIPGeoData(ipAddress string) (*ipBaseResponse, error) {
142+
response := &ipBaseResponse{}
143+
ipBaseError := &IPBaseError{}
75144

76-
resp, err := g.FreeGeoIPClient.R().
145+
resp, err := g.IPBaseClient.R().
77146
SetHeader("Accept", "application/json").
78147
SetQueryParam("apikey", g.Token).
79-
SetResult(freeGeoIPResponse).
80-
SetError(freeGeoIPError).
81-
Get(ipAddress)
148+
SetQueryParam("ip", ipAddress).
149+
SetResult(response).
150+
SetError(ipBaseError).
151+
Get("/info")
82152
if err != nil {
83-
return freeGeoIPResponse, err
153+
return response, err
84154
}
85155

86156
// If api gives back status code >399, report error to user
87157
if resp.IsError() {
88-
return freeGeoIPResponse, freeGeoIPError
158+
return response, ipBaseError
89159
}
90160

91-
return resp.Result().(*FreeGeoIPResponse), nil
161+
return resp.Result().(*ipBaseResponse), nil
92162
}
93163

94164
// New creates a new geofence for the IP address specified.
95165
// Use "" as the ip address to geofence the machine your application is running on
96-
// Token comes from https://freegeoip.app/
166+
// Token comes from https://ipbase.com/
97167
func New(c *Config) (*Geofence, error) {
98-
// Create new client for freegeoip.app
99-
freeGeoIPClient := resty.New().SetBaseURL(freeGeoIPBaseURL)
168+
// Create new client for ipbase.com
169+
IPBaseClient := resty.New().SetBaseURL(ipBaseBaseURL)
100170

101171
// New Geofence object
102172
geofence := &Geofence{
103-
Config: *c,
104-
FreeGeoIPClient: freeGeoIPClient,
105-
Cache: cache.New(c.CacheTTL, deleteExpiredCacheItemsInternal),
173+
Config: *c,
174+
IPBaseClient: IPBaseClient,
175+
Cache: cache.New(c.CacheTTL, deleteExpiredCacheItemsInternal),
106176
}
107177

108178
// Get current location of specified IP address
@@ -114,8 +184,8 @@ func New(c *Config) (*Geofence, error) {
114184
}
115185

116186
// Set the location of our geofence to compare against looked up IP's
117-
geofence.Latitude = ipAddressLookupDetails.Latitude
118-
geofence.Longitude = ipAddressLookupDetails.Longitude
187+
geofence.Latitude = ipAddressLookupDetails.Data.Location.Latitude
188+
geofence.Longitude = ipAddressLookupDetails.Data.Location.Longitude
119189

120190
return geofence, nil
121191
}
@@ -148,7 +218,7 @@ func (g *Geofence) IsIPAddressNear(ipAddress string) (bool, error) {
148218

149219
// Format our IP coordinates and the clients
150220
currentCoordinates := geo.NewCoordinatesFromDegrees(g.Latitude, g.Longitude)
151-
clientCoordinates := geo.NewCoordinatesFromDegrees(ipAddressLookupDetails.Latitude, ipAddressLookupDetails.Longitude)
221+
clientCoordinates := geo.NewCoordinatesFromDegrees(ipAddressLookupDetails.Data.Location.Latitude, ipAddressLookupDetails.Data.Location.Longitude)
152222

153223
// Get distance in kilometers
154224
distance := currentCoordinates.Distance(clientCoordinates)

0 commit comments

Comments
 (0)