From bbc0a9c4b2cb0c162dbce52bbb650b8313f1b38b Mon Sep 17 00:00:00 2001 From: Rob Barrie <96049667+rbarrielabrystech@users.noreply.github.com> Date: Fri, 13 Mar 2026 22:59:26 +0000 Subject: [PATCH 1/2] feat: add missing PlusAnonymous fields and fix PlusMobile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PlusAnonymous: add IsResProxy, LastSeen, and PercentDaysSeen fields to match the IPinfo Max /lookup API response. These fields provide residential proxy detection and anonymiser recency/frequency signals that were previously silently dropped during JSON unmarshaling. PlusMobile: replace incorrect Name field with CountryCode to match the actual API response schema (the mobile object returns mcc, mnc, and country_code — not name). Update lookup-plus example to demonstrate the new fields. Co-Authored-By: Claude Opus 4.6 --- example/lookup-plus/main.go | 13 +++++++++---- ipinfo/plus.go | 23 +++++++++++++++-------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/example/lookup-plus/main.go b/example/lookup-plus/main.go index a25a548..0e92c8f 100644 --- a/example/lookup-plus/main.go +++ b/example/lookup-plus/main.go @@ -36,12 +36,17 @@ func main() { fmt.Printf("AS Type: %s\n", info.AS.Type) } if info.Mobile != nil { - fmt.Printf("Mobile - Name: %s, MCC: %s, MNC: %s\n", - info.Mobile.Name, info.Mobile.MCC, info.Mobile.MNC) + fmt.Printf("Mobile - MCC: %s, MNC: %s, Country: %s\n", + info.Mobile.MCC, info.Mobile.MNC, info.Mobile.CountryCode) } if info.Anonymous != nil { - fmt.Printf("Anonymous - Proxy: %v, Relay: %v, Tor: %v, VPN: %v\n", - info.Anonymous.IsProxy, info.Anonymous.IsRelay, info.Anonymous.IsTor, info.Anonymous.IsVPN) + fmt.Printf("Anonymous - Proxy: %v, Relay: %v, Tor: %v, VPN: %v, ResProxy: %v\n", + info.Anonymous.IsProxy, info.Anonymous.IsRelay, info.Anonymous.IsTor, + info.Anonymous.IsVPN, info.Anonymous.IsResProxy) + if info.Anonymous.Name != "" { + fmt.Printf("Anonymous Service: %s (last seen: %s, %d%% of days)\n", + info.Anonymous.Name, info.Anonymous.LastSeen, info.Anonymous.PercentDaysSeen) + } } fmt.Printf("Anonymous: %v\n", info.IsAnonymous) fmt.Printf("Anycast: %v\n", info.IsAnycast) diff --git a/ipinfo/plus.go b/ipinfo/plus.go index 1a3abc3..af141f5 100644 --- a/ipinfo/plus.go +++ b/ipinfo/plus.go @@ -91,18 +91,25 @@ type PlusAS struct { // PlusMobile represents the mobile object in Plus API response. type PlusMobile struct { - Name string `json:"name,omitempty"` - MCC string `json:"mcc,omitempty"` - MNC string `json:"mnc,omitempty"` + MCC string `json:"mcc,omitempty"` + MNC string `json:"mnc,omitempty"` + CountryCode string `json:"country_code,omitempty"` } // PlusAnonymous represents the anonymous object in Plus API response. type PlusAnonymous struct { - IsProxy bool `json:"is_proxy"` - IsRelay bool `json:"is_relay"` - IsTor bool `json:"is_tor"` - IsVPN bool `json:"is_vpn"` - Name string `json:"name,omitempty"` + IsProxy bool `json:"is_proxy"` + IsRelay bool `json:"is_relay"` + IsTor bool `json:"is_tor"` + IsVPN bool `json:"is_vpn"` + IsResProxy bool `json:"is_res_proxy"` + Name string `json:"name,omitempty"` + LastSeen string `json:"last_seen,omitempty"` + + // PercentDaysSeen is the percentage of days the IP was seen using an + // anonymous service over the trailing 90 days. Higher values indicate + // more persistent anonymiser usage. + PercentDaysSeen int `json:"percent_days_seen"` } // PlusAbuse represents the abuse object in Plus API response. From d068586f0af43756361ff67f49bc6d07482e225e Mon Sep 17 00:00:00 2001 From: Silvano Cerza Date: Thu, 26 Mar 2026 16:59:12 +0100 Subject: [PATCH 2/2] Revert changes to PlusMobile data structure --- example/lookup-plus/main.go | 4 ++-- ipinfo/plus.go | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/example/lookup-plus/main.go b/example/lookup-plus/main.go index 0e92c8f..eb25134 100644 --- a/example/lookup-plus/main.go +++ b/example/lookup-plus/main.go @@ -36,8 +36,8 @@ func main() { fmt.Printf("AS Type: %s\n", info.AS.Type) } if info.Mobile != nil { - fmt.Printf("Mobile - MCC: %s, MNC: %s, Country: %s\n", - info.Mobile.MCC, info.Mobile.MNC, info.Mobile.CountryCode) + fmt.Printf("Mobile - Name: %s, MCC: %s, MNC: %s\n", + info.Mobile.Name, info.Mobile.MCC, info.Mobile.MNC) } if info.Anonymous != nil { fmt.Printf("Anonymous - Proxy: %v, Relay: %v, Tor: %v, VPN: %v, ResProxy: %v\n", diff --git a/ipinfo/plus.go b/ipinfo/plus.go index af141f5..3873882 100644 --- a/ipinfo/plus.go +++ b/ipinfo/plus.go @@ -91,9 +91,9 @@ type PlusAS struct { // PlusMobile represents the mobile object in Plus API response. type PlusMobile struct { - MCC string `json:"mcc,omitempty"` - MNC string `json:"mnc,omitempty"` - CountryCode string `json:"country_code,omitempty"` + Name string `json:"name,omitempty"` + MCC string `json:"mcc,omitempty"` + MNC string `json:"mnc,omitempty"` } // PlusAnonymous represents the anonymous object in Plus API response.