|
| 1 | +package location |
| 2 | + |
| 3 | +import ( |
| 4 | + "encoding/json" |
| 5 | + "errors" |
| 6 | + "fmt" |
| 7 | + "log" |
| 8 | + "net" |
| 9 | + "net/http" |
| 10 | +) |
| 11 | + |
| 12 | +const IpGeoLocationApiKey = "71a993e55ea64df29c3caa7c094f7099" |
| 13 | + |
| 14 | +// https://ipgeolocation.io/ data |
| 15 | +// 1k request for per day |
| 16 | + |
| 17 | +type IpgeolocationInfo struct { |
| 18 | + IP string `json:"ip"` |
| 19 | + Hostname string `json:"hostname"` |
| 20 | + ContinentCode string `json:"continent_code"` |
| 21 | + ContinentName string `json:"continent_name"` |
| 22 | + CountryCode2 string `json:"country_code2"` |
| 23 | + CountryCode3 string `json:"country_code3"` |
| 24 | + CountryName string `json:"country_name"` |
| 25 | + CountryCapital string `json:"country_capital"` |
| 26 | + StateProv string `json:"state_prov"` |
| 27 | + District string `json:"district"` |
| 28 | + City string `json:"city"` |
| 29 | + Zipcode string `json:"zipcode"` |
| 30 | + Latitude string `json:"latitude"` |
| 31 | + Longitude string `json:"longitude"` |
| 32 | + IsEu bool `json:"is_eu"` |
| 33 | + CallingCode string `json:"calling_code"` |
| 34 | + CountryTld string `json:"country_tld"` |
| 35 | + Languages string `json:"languages"` |
| 36 | + CountryFlag string `json:"country_flag"` |
| 37 | + GeonameID string `json:"geoname_id"` |
| 38 | + Isp string `json:"isp"` |
| 39 | + ConnectionType string `json:"connection_type"` |
| 40 | + Organization string `json:"organization"` |
| 41 | + Asn string `json:"asn"` |
| 42 | + Currency Currency `json:"currency"` |
| 43 | + TimeZone TimeZone `json:"time_zone"` |
| 44 | +} |
| 45 | +type Currency struct { |
| 46 | + Code string `json:"code"` |
| 47 | + Name string `json:"name"` |
| 48 | + Symbol string `json:"symbol"` |
| 49 | +} |
| 50 | +type TimeZone struct { |
| 51 | + Name string `json:"name"` |
| 52 | + Offset int `json:"offset"` |
| 53 | + CurrentTime string `json:"current_time"` |
| 54 | + CurrentTimeUnix float64 `json:"current_time_unix"` |
| 55 | + IsDst bool `json:"is_dst"` |
| 56 | + DstSavings int `json:"dst_savings"` |
| 57 | +} |
| 58 | + |
| 59 | +// GetIpgeolocationInfo |
| 60 | +// |
| 61 | +// @Description: 使用ipgeolocation 获取geoip信息 |
| 62 | +// @param ipString |
| 63 | +// @return *IpgeolocationInfo |
| 64 | +// @return error |
| 65 | +func GetIpgeolocationInfo(ipString string) (*IpgeolocationInfo, error) { |
| 66 | + normalIpv4Address := CheckStrIsIpAddress(ipString) |
| 67 | + if !normalIpv4Address { |
| 68 | + return nil, errors.New("args not a valid ipStr address: " + ipString) |
| 69 | + } |
| 70 | + var requestUrl = fmt.Sprintf("https://api.ipgeolocation.io/ipgeo?apiKey=%s&ip=%s", IpGeoLocationApiKey, ipString) |
| 71 | + req, err := http.NewRequest("GET", requestUrl, nil) |
| 72 | + if err != nil { |
| 73 | + log.Println("get location by ipgeolocation error: ", err) |
| 74 | + return nil, errors.New("get location by ipgeolocation error: " + err.Error()) |
| 75 | + } |
| 76 | + req.Header.Add("Accept", "*/*") |
| 77 | + req.Header.Add("Accept-Language", "zh,en;q=0.9,zh-TW;q=0.8,zh-CN;q=0.7,ja;q=0.6") |
| 78 | + req.Header.Add("Cache-Control", "no-cache") |
| 79 | + //req.Header.Add("Origin", "http://ip-api.com") |
| 80 | + req.Header.Add("Pragma", "no-cache") |
| 81 | + //req.Header.Add("Referer", "http://ip-api.com/") |
| 82 | + req.Header.Add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36") |
| 83 | + |
| 84 | + client := &http.Client{} |
| 85 | + resp, err := client.Do(req) |
| 86 | + defer resp.Body.Close() |
| 87 | + |
| 88 | + var ipGeoInfo IpgeolocationInfo |
| 89 | + err = json.NewDecoder(resp.Body).Decode(&ipGeoInfo) |
| 90 | + if err != nil { |
| 91 | + log.Println("get location by ipgeolocation error: ", err) |
| 92 | + return nil, errors.New("get location by ipgeolocation error: " + err.Error()) |
| 93 | + } |
| 94 | + return &ipGeoInfo, nil |
| 95 | +} |
| 96 | + |
| 97 | +// GetLocInfoShort |
| 98 | +// |
| 99 | +// @Description: 获取地理位置信息 |
| 100 | +// @receiver receiver |
| 101 | +// @return string |
| 102 | +func (receiver *IpgeolocationInfo) GetLocInfoShort() string { |
| 103 | + if receiver == nil { |
| 104 | + return "" |
| 105 | + } |
| 106 | + return fmt.Sprintf("%s-%s-%s", receiver.CountryCode3, receiver.City, receiver.Organization) |
| 107 | +} |
| 108 | + |
| 109 | +// CheckStrIsIpAddress |
| 110 | +// |
| 111 | +// @Description: 判断str是否为合格的ip str |
| 112 | +// @param str |
| 113 | +// @return bool |
| 114 | +func CheckStrIsIpAddress(str string) bool { |
| 115 | + ip := net.ParseIP(str) |
| 116 | + return ip != nil |
| 117 | +} |
0 commit comments