Search code examples
vbscriptasp-classic

How to use Global.asa with API


I am attempting to use an API to return a website visitor's latitude, longitude, city, state, and zip code. I found one I like - GEO IPIFY

Challenge I have is my website(s) is done in classic ASP and the examples for the API are in C#, JAVA, Python, etc.

What I am trying to achieve is getting the needed values, lat, lng, zip, etc, in my global.asa and setting them as session variables. The example below is for VB.net.

Imports System
Imports System.Net
Imports System.IO

Class Program
    Public Const IP As String = "63.148.239.195"
    Public Const API_KEY As String = "at_6ZsRWjq..."
    Public Const API_URL As String = "https://geo.ipify.org/api/v1?"

    Private Shared Sub Main()
        Dim url As String = API_URL & $"apiKey={API_KEY}&ipAddress={IP}"
        Dim resultData As String = String.Empty
        Dim req As HttpWebRequest = CType(WebRequest.Create(url), HttpWebRequest)
        Using response As HttpWebResponse = CType(req.GetResponse(), HttpWebResponse)
            Using stream As Stream = response.GetResponseStream()
                Using reader As StreamReader = New StreamReader(stream)
                    resultData = reader.ReadToEnd()
                End Using
            End Using
        End Using
        Console.WriteLine(resultData)
    End Sub
End Class

Solution

  • Global.asa has a Session_OnStart sub, but you're quite limited in what you can do within the Global.asa file, so trying to call the API from Session_OnStart is going to lead to issues. You also can't use Session_OnStart outside of Global.asa or call any functions or sub routines from within Global.asa unless the functions/subs are also coded into Global.asa.

    What I like to do is create a global.asp file, which I use to set various application settings, include site-wide classes and store important functions and sub routines that are needed throughout my site. I then include global.asp on all pages of my asp site. Within global.asp you could set a sub that calls the ipify.org api and stores the results as session variables with the help of a JSON class. You could then call the sub on each page load and exit the sub if the api has already been called during the users session, or make a new call if it's a new session.

    global.asp

    <%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
    <%
    
        ' Set some useful application settings, constants, other site-wide classes etc...
    
        Server.ScriptTimeout = 20
        Session.Timeout = 720
        Response.Charset = "UTF-8"
        Response.LCID = 1033
    
    %>
    <!--#include virtual = "/classes/jsonObject.class.asp" -->
    <%
    
        Sub ipify()
    
            ' Only call the ipify API once per session (but try 3 times)
            ' If session("ipify_called") is true or 3+ attempts have been  
            ' made to call the API then exit the sub
    
            if session("ipify_called") OR session("ipify_attempts") >= 3 then exit sub
    
            ' Assign a value of 0 to ipify_attempts if this is a new session
    
            if isEmpty(session("ipify_attempts")) then session("ipify_attempts") = 0
    
            Const api_key = "YOUR_API_KEY"
            Const api_url = "https://geo.ipify.org/api/v1"
    
            Dim rest : Set rest = Server.CreateObject("MSXML2.ServerXMLHTTP")
            rest.open "GET", api_url, False
            rest.send "apiKey=" & api_key & "&ipAddress=" & Request.ServerVariables("REMOTE_ADDR")
    
            if rest.status = 200 then
    
                Dim JSON : Set JSON = New JSONobject
                Dim oJSONoutput : Set oJSONoutput = JSON.Parse(rest.responseText)
    
                    if isObject(oJSONoutput("location")) then
    
                        session("ipify_country") = oJSONoutput("location")("country")
                        session("ipify_region") = oJSONoutput("location")("region")
                        session("ipify_city") = oJSONoutput("location")("city")
                        session("ipify_lat") = oJSONoutput("location")("lat")
                        session("ipify_lng") = oJSONoutput("location")("lng")
                        session("ipify_postalCode") = oJSONoutput("location")("postalCode")
                        session("ipify_timezone") = oJSONoutput("location")("timezone")
    
                        ' To prevent the api from being called again during this session
    
                        session("ipify_called") = true
    
                    else
    
                        ' oJSONoutput("location") should be an object, but it isn't.
                        ' The rest.responseText is probably invalid
    
                        session("ipify_attempts") = session("ipify_attempts") + 1
    
                    end if
    
                Set oJSONoutput = nothing
                Set JSON = nothing
    
            else
    
                ' Unexpected status code, probably a good idea to log the rest.responseText
    
                session("ipify_attempts") = session("ipify_attempts") + 1
    
            end if
    
            set rest = nothing
    
        End Sub
    
    
        ' Call the ipify sub on each page load.
    
        Call ipify()
    
    %>
    

    JSON Class used: https://github.com/rcdmk/aspJSON

    Be sure to include global.asp on other pages of your asp site:

    <!--#include virtual = "/global.asp" -->