This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

IP-Api.com Simple IP info TCL

Support & discussion of released scripts, and announcements of new releases.
Post Reply
H
Henkie2
Voice
Posts: 34
Joined: Fri Sep 25, 2015 2:55 pm

IP-Api.com Simple IP info TCL

Post by Henkie2 »

Trying to learn some TCL and API, this is my first simple script. Maybe the code is not the best, all tips and hints are welcome.

(trying to get JSON to work only the end not works, to get the error message no data found, any one can help?)

Usage: !ip 127.0.0.1 or !ip mydomain.com to get channel results from ip-api.com
use https as url to get https!

Results are:
status,message,country,countryCode,region,regionName,city,zip,lat,lon,timezone,isp,org,as,query

XML version

Code: Select all

# -----------------------------------
# IP/DOMAIN API info from ip-api.com
# -----------------------------------

  # Setup the triggers
  bind pub - !ip ipapi
  bind pub - !host ipapi
  bind pub - !ipapi ipapi

proc ipapi {nick host hand chan txt} {
  package require http
  if {![catch {package require tls}]} { ::http::register https 443 [list ::tls::socket -autoservername true] }
  if {![llength [split $txt]]} {
    putserv "notice $nick :Use: !ip 127.0.0.1 or !ip mydomain.com"
    return 0
  }
  # XML regexp api request
  set url "http://ip-api.com/xml/$txt" 
  set page [http::data [http::geturl $url -timeout 10000]]
  ::http::cleanup $page
  ::http::unregister https
  
  # Page=status,message,country,countryCode,region,regionName,city,zip,lat,lon,timezone,isp,org,as,query
  regexp {<isp>(.*?)<\/isp>} $page a isp
  regexp {<country>(.*?)<\/country>} $page a country
  regexp {<timezone>(.*?)<\/timezone>} $page a timezone
  regexp {<status>(.*?)<\/status>} $page a status
  regexp {<city>(.*?)<\/city>} $page a city
  regexp {<regionName>(.*?)<\/regionName>} $page a regionName
  regexp {<lat>(.*?)<\/lat>} $page a lat
  regexp {<lon>(.*?)<\/lon>} $page a lon
  regexp {<zip>(.*?)<\/zip>} $page a zip
  regexp {<org>(.*?)<\/org>} $page a org
  regexp {<query>([0-9]+(\.[0-9]+)+)</query>} $page a query
  regexp {<hosting>(.*?)<\/hosting>} $page a hosting
  regexp {<proxy>(.*?)<\/proxy>} $page a proxy
  regexp {<mobile>(.*?)<\/mobile>} $page a mobile
  
  # Announce to channel
  if {[info exists country]} {
        putserv "privmsg $chan :\00303IP-API:\003 $query \00303ISP:\003 $isp \00303ORG:\003 $org \00303COUNTRY:\003 $country"
  if {[info exists lat]} {
        putserv "privmsg $chan :\00303IP-API:\003 \00303CITY:\003 $city ($zip) \00303REGION:\003 $regionName ($lat,$lon) \00303TIMEZONE:\003 $timezone"
  }
  if {[info exists hosting]} {
        putserv "privmsg $chan :\00303IP-API:\003 \00303HOSTING:\003 $hosting \00303PROXY:\003 $proxy \00303MOBILE:\003 $mobile"
  }
  } else {  putserv "privmsg $chan :\00303IP-API:\003 No data found. Used correct IP/Domain?" }
}

  putlog "\[SCRiPT\] IP-API XML Info :: Loaded successfully."
JSON version

Code: Select all

# -----------------------------------
# IP/DOMAIN API info from ip-api.com
# -----------------------------------

 bind pub - !ip ipapiproc
 bind pub - !host ipapiproc
 bind pub - !ipapi ipapiproc
 bind pub - !ipinfo ipapiproc

 package require http
 package require tls
 package require json

proc ipapiproc {nick host hand chan text} {
 ::http::register https 443 [list ::tls::socket -autoservername true]
 if {![llength [split $text]]} {
 putserv "NOTICE $nick :Use: !ip 127.0.0.1 or !ip mydomain.com"
 return 0
 }
 # JSON regexp API call
 set url "http://ip-api.com/json/$text" 
 set token [::http::geturl $url -timeout 10000]
 set page [::http::data $token]
 upvar 0 $token state
 if {$state(status) ne "ok"} {
 putserv "PRIVMSG $chan :\00303IP-API:\003 $state(url) made $state(status) error"
 return 0
 }
 ::http::cleanup $token
 ::http::unregister https

 # $page is the result of your geturl
 # Page=status,message,country,countryCode,region,regionName,city,zip,lat,lon,timezone,isp,org,as,asn,query,continent,continentCode,currency,asname,mobile,proxy,hosting
 set data [json::json2dict $page]
 set ip [string map {" " ":"} [dict get $data query]]
 set isp [dict get $data isp]
 set country [dict get $data country]
 set countryCode [dict get $data countryCode]
 set org [dict get $data org]
 set city [dict get $data city]
 set zip [dict get $data zip]
 set regionName [dict get $data regionName]
 set lat [dict get $data lat]
 set lon [dict get $data lon]
 # Works only on HTTPS (paid service)
 #if { [dict get $data mobile] eq "true"} { set mobile avaible } else  { set mobile n/a }
 #if { [dict get $data proxy] eq "true"} { set proxy avaible } else  { set proxy n/a }
 #if { [dict get $data hosting] eq "true"} { set hosting avaible } else  { set hosting n/a }

 # Announce data to $chan
 if {[dict get $data status] eq "fail"} {
 set status [dict get $data message]
 putserv "PRIVMSG $chan :\00303IP-API:\003 $message ($ip). Used correct IP/Domain?"
 return  0
 }
 if {[info exists country]} {
 putserv "PRIVMSG $chan :\00303IP-API:\003 $ip - \00303ISP:\003 $isp \00303ORG:\003 $org \00303COUNTRY:\003 $countryCode, $country"
 }
 if {[info exists lat]} {
 putserv "PRIVMSG $chan :\00303IP-API:\003 \00303CITY:\003 $city \00303ZIP:\003 $zip\00303 REGION:\003 $regionName ($lat,$lon)"
 }
 if {[info exists mobile]} {
 putserv "PRIVMSG $chan :\00303IP-API:\003 \00303HOSTING:\003 $hosting \00303PROXY:\003 $proxy \00303MOBILE:\003 $mobile"
 }
 else {
 putserv "PRIVMSG $chan :\00303IP-API:\003 No data found. Used correct IP/Domain?"
 }
}

  putlog "\[SCRiPT\] IP-API Info :: Loaded successfully."

  
Last edited by Henkie2 on Thu Dec 21, 2023 5:42 pm, edited 15 times in total.
User avatar
CrazyCat
Revered One
Posts: 1242
Joined: Sun Jan 13, 2002 8:00 pm
Location: France
Contact:

Re: IP-Api.com Simple IP info TCL

Post by CrazyCat »

ip-api returns a json, so use json package to parse it (json2dict), don't treat it as simple string.

And I'm sure there is already ip-api script samples in this forum.
If not, here is a small tip:
# $page is the result of your geturl
set data [::json2dict $page]
set ip [string map {" " ":"} [dict get $data query]]
set country [dict get $data country]
set city [dict get $data city]
set lat [dict get $data lat]
set lon [dict get $data lon]
set isp [dict get $data isp]
set org [dict get $data org]
set asn [dict get $data as]
set asname [dict get $data asname]
if { [dict get $data mobile] eq "true"} { set mobile 1 } else  { set mobile 0 }
if { [dict get $data proxy] eq "true"} { set proxy 1 } else  { set proxy 0 }
if { [dict get $data hosting] eq "true"} { set hosting 1 } else  { set hosting 0 }
H
Henkie2
Voice
Posts: 34
Joined: Fri Sep 25, 2015 2:55 pm

Re: IP-Api.com Simple IP info TCL

Post by Henkie2 »

Thx for the tips they all welcome, and i searched before i started to make this one.
Going to use that json to get some basics ^^
H
Henkie2
Voice
Posts: 34
Joined: Fri Sep 25, 2015 2:55 pm

Re: IP-Api.com Simple IP info TCL

Post by Henkie2 »

CrazyCat wrote: Thu Dec 14, 2023 4:25 am ip-api returns a json, so use json package to parse it (json2dict), don't treat it as simple string.

And I'm sure there is already ip-api script samples in this forum.
If not, here is a small tip:
# $page is the result of your geturl
set data [::json2dict $page]
set ip [string map {" " ":"} [dict get $data query]]
set country [dict get $data country]
set city [dict get $data city]
set lat [dict get $data lat]
set lon [dict get $data lon]
set isp [dict get $data isp]
set org [dict get $data org]
set asn [dict get $data as]
set asname [dict get $data asname]
if { [dict get $data mobile] eq "true"} { set mobile 1 } else  { set mobile 0 }
if { [dict get $data proxy] eq "true"} { set proxy 1 } else  { set proxy 0 }
if { [dict get $data hosting] eq "true"} { set hosting 1 } else  { set hosting 0 }

Code: Select all

# -----------------------------------
# IP/DOMAIN API info from ip-api.com
# -----------------------------------

  bind pub - !ip ipapi
  bind pub - !ipapi ipapi
  bind pub - !ipinfo ipapi

  package require http
  package require tls
  package require json
  
proc ipapi {nick host hand chan arg} {
  http::register https 443 [list ::tls::socket -autoservername true]
  if {![llength [split $arg]]} {
    putserv "notice $nick :Use: !ip 127.0.0.1 or !ip mydomain.com"
    return 0
  }
  # JSON regexp
  set url "http://ip-api.com/json/$arg" 
  set page [http::data [http::geturl $url -timeout 10000]]
  ::http::cleanup $page
  ::http::unregister https
  
  # Page=status,message,country,countryCode,region,regionName,city,zip,lat,lon,timezone,isp,org,as,query
  # $page is the result of your geturl
  set data [::json2dict $page]
  set country [dict get $data country]
  putserv "privmsg $chan :IP-API: $arg $country"
  
}
I'm just trying to get data on country to test only no results. What i'm doing wrong?
User avatar
CrazyCat
Revered One
Posts: 1242
Joined: Sun Jan 13, 2002 8:00 pm
Location: France
Contact:

Re: IP-Api.com Simple IP info TCL

Post by CrazyCat »

This part is false:
set page [http::data [http::geturl $url -timeout 10000]]
::http::cleanup $page
::http::unregister https
It must be:
set token [::http::geturl $url -timeout 10000]
set page [::http::data $token]
# putlog "Got this in page: $page"
::http::cleanup $token
::http::unregister https
And you can uncomment the putlog to see if something is stored in $page
H
Henkie2
Voice
Posts: 34
Joined: Fri Sep 25, 2015 2:55 pm

Re: IP-Api.com Simple IP info TCL

Post by Henkie2 »

CrazyCat wrote: Thu Dec 14, 2023 7:28 pm This part is false:
set page [http::data [http::geturl $url -timeout 10000]]
::http::cleanup $page
::http::unregister https
It must be:
set token [::http::geturl $url -timeout 10000]
set page [::http::data $token]
# putlog "Got this in page: $page"
::http::cleanup $token
::http::unregister https
And you can uncomment the putlog to see if something is stored in $page
@CrazyCat thanks for all your help and support, much appreciated. Going to trying that !stream now from tvmaze :D
btw i had to use this: To get data to chan.
set data [dict get [json::json2dict $page]] to get the announce
are there so many json calls? like regexp this was not that simpel for me :D
Have learned alot i guess, thx once more. Njoy the weekend

Code: Select all

  # this one not worked
  set data [::json2dict $page] 
  #also not wrked
  set data [::json::json2dict [http::data $page]] 
  #this one worked
  set data [dict get [json::json2dict $page]]
  #showing results
  set country [dict get $data country]

  putserv "PRIVMSG $chan :IP-API: $country"

This is the JSON version

Code: Select all

# -----------------------------------
# IP/DOMAIN API info from ip-api.com
# -----------------------------------

  bind pub - !ip ipapiproc
  bind pub - !ipapi ipapiproc
  bind pub - !ipinfo ipapiproc

  package require http
  package require tls
  package require json
  
proc ipapiproc {nick host hand chan text} {
  http::register https 443 [list ::tls::socket -autoservername true]
  if {![llength [split $text]]} {
    putserv "NOTICE $nick :Use: !ip 127.0.0.1 or !ip mydomain.com"
    return 0
  }
  # JSON regexp
  set url "http://ip-api.com/json/$text" 
  set token [::http::geturl $url -timeout 10000]
  set page [::http::data $token]
  upvar 0 $token state
  if {$state(status) ne "ok"} {
   putlog "HTTP Error : $state(url) made $state(status) error"
   return 1
  }
  ::http::cleanup $token
  ::http::unregister https
  
  # Page=status,message,country,countryCode,region,regionName,city,zip,lat,lon,timezone,isp,org,as,asn,query,continent,continentCode,currency,asname,mobile,proxy,hosting
  # $page is the result of your geturl
  set data [dict get [json::json2dict $page]]
  set ip [string map {" " ":"} [dict get $data query]]
  set isp [dict get $data isp]
  set country [dict get $data country]
  set org [dict get $data org]
  set city [dict get $data city]
  set regionName [dict get $data regionName]
  set lat [dict get $data lat]
  set lon [dict get $data lon]
  if { [dict get $data status] eq "succes"} { set status Failed } else { set status Succes }
  # Works only on HTTPS and url needs to be set as:  https://ip-api.com/$text
  #if { [dict get $data mobile] eq "true"} { set mobile avaible } else  { set mobile n/a }
  #if { [dict get $data proxy] eq "true"} { set proxy avaible } else  { set proxy n/a }
  #if { [dict get $data hosting] eq "true"} { set hosting avaible } else  { set hosting n/a }
  
  if {[info exists country]} {
    putserv "PRIVMSG $chan :IP-API: $ip - SP: $isp - ORG: $org - COUNTRY: $country"
  if {[info exists lat]} {
    putserv "PRIVMSG $chan :IP-API: STATUS: $status - CITY: $city - REGION: $regionName ($lat,$lon)"
  if {[info exists mobile]} {
    putserv "PRIVMSG $chan :IP-API: HOSTING: $hosting - PROXY: $proxy - MOBILE: $mobile"
  else { putserv "PRIVMSG $chan :IP-API: Invalid address or IP not found" }
   }
  }
 }
}
  putlog "\[SCRiPT\] IP-API Info :: Loaded successfully."
Last edited by Henkie2 on Fri Dec 15, 2023 8:43 pm, edited 5 times in total.
H
Henkie2
Voice
Posts: 34
Joined: Fri Sep 25, 2015 2:55 pm

Re: IP-Api.com Simple IP info TCL

Post by Henkie2 »

One last question :D How to set if timout error is passed or site is offline? how to show error on tcl?
User avatar
CrazyCat
Revered One
Posts: 1242
Joined: Sun Jan 13, 2002 8:00 pm
Location: France
Contact:

Re: IP-Api.com Simple IP info TCL

Post by CrazyCat »

Henkie2 wrote: Fri Dec 15, 2023 2:39 pm One last question :D How to set if timout error is passed or site is offline? how to show error on tcl?
After the line:
set page [::http::data $token]
You can use this kind of code:
upvar 0 $token state
if {$state(status) ne "ok"} {
   putlog "HTTP Error : $state(url) made $state(status) error"
   return 1
}
You can have a look to https://www.tcl-lang.org/man/tcl/TclCmd/http.htm to learn more about http package
H
Henkie2
Voice
Posts: 34
Joined: Fri Sep 25, 2015 2:55 pm

Re: IP-Api.com Simple IP info TCL

Post by Henkie2 »

Thx once again, will keep that link ^^

*Updated JSON version
H
Henkie2
Voice
Posts: 34
Joined: Fri Sep 25, 2015 2:55 pm

Re: IP-Api.com Simple IP info TCL

Post by Henkie2 »

Just noticed that if false ip or domain the else msg to chan not working.
How can i ask json if data is empty or 0 show error log? Thx once more
Post Reply