Munender Singh
Mega Sage

There is a proposed solution to fetch the details of a location record suce as latitude,longitude,timezone,offset etc based on the address fields such as street,city,country in servicenow.

This requires the Google API which needs a google key to genenerate this.So,please follow this link to generate the google key.

https://developers.google.com/maps/documentation/javascript/get-api-key

Now after fetching the key,perform these steps.Please note I have created two new field u_timezone and u_offset on cmn_location location table for capturing these details.

Table:Location

Business rule type:before

when to run:insert/update

 

1. To update latitude and longitude

condition:current.street.changes() || current.city.changes() || current.state.changes() || current.zip.changes() || current.country.changes()

script:

(function executeRule(current, previous /*null when async*/) {


if (current != null) {
var street = new String(current.street);
street = street.replaceAll("\r","");
street = street.replaceAll("\n"," ");
street = street.replaceAll(" ","+");


var city = new String(current.city).replaceAll(" ","+");
var state = new String(current.state).replaceAll(" ","+");
var zip = new String(current.zip).replaceAll(" ","+");


var address = "address=" + street + "," + city + "," + state + "," + zip + "&key='GOOGLE_API_KEY";


var ws = new HTTPAdaptor("https://maps.googleapis.com/maps/api/geocode/json?");
var ret = ws.doGet(address);

var lat = 0,
lng = 0;

try {
var output = new JSONParser().parse(ret);


if (output.status == "OK") {


lat = output['results'][0]['geometry']['location']['lat']; //process the o/p to fetch latitude
lng = output['results'][0]['geometry']['location']['lng']; //process the o/p to fetch longitude


current.latitude = lat; //set the latitude
current.longitude = lng; //set the longitude
}

else {

gs.logErr("Get_Lat_Long Lookup Error: " + output.status);

gs.logErr("Address: " + address);
gs.logErr("API Response: " + ret);
}


} catch (err) {
gs.logErr("Geocoding error: " + jsonOutput);
}
}

})(current, previous);

 

2. To update timezone and offset

condition:current.latitude.changes() || current.longitude.changes() 

script:

rawOffset

(function executeRule(current, previous /*null when async*/) {

if (current != null) {

var lat = new String(current.latitude).replaceAll(" ","+");
var lon = new String(current.longitude).replaceAll(" ","+");

var address = "location=" + lat +','+lon +"&timestamp=1478880000&key='Google_API_KEY'";

var ws = new HTTPAdaptor("https://maps.googleapis.com/maps/api/timezone/json?");

var ret = ws.doGet(address);

var tz = 0;

try {
var output = new JSONParser().parse(ret);

if (output.status == "OK") {
current.u_timezone = output.timeZoneId; //set the timezone

current.u_offset = output.rawOffset; //set the offset

} else {


gs.logErr("Get_Lat_Long Lookup Error: " + output.status);

gs.logErr("Address: " + address);

gs.logErr("API Response: " + ret);


}


} catch (err) {


gs.logErr("Geocoding error: " + jsonOutput);


}
}
})(current, previous);

 

 

Regards,

Munender

Comments
Mike Naputano
Tera Expert

Hi Munender,

   I have a need to configure this for a customer I am working with, but I cannot seem to get a few things set properly with your code. I realize this post is 3 years old, but there is an out of box business rule that captures the latitude and longitude of a location (get_lat_long on the locations table) and there is an out of box time zone field on the locations table (time_zone).

I have created the business rule you show here to update time zone and offset,  I assume that is a before update business rule? The script fails with an error 'com.glide.script.RhinoEcmaError: "rawOffset" is not defined.' if I copy your code above.

Do we need to replace 'Google_API_KEY' with our key we created?

I did create a custom time zone and offset field on the locations table, just to see if anything gets added to those fields. I assume those fields are string fields?

Any guidance would be greatly appreciated!

Thanks,

Mike

Munender Singh
Mega Sage

Hello Mike,

 

Sorry for delay in response as it was a weekend 🙂

1. Yes, the Business Rule type is 'before'

2. Yes, please use your own key to replace 'Google_API_KEY' 

3. Both custom fields created are STRING type

 

Please check and let me know if any issues.

 

Regards,

Munender

 

Mike Naputano
Tera Expert

Hi Munender,

   Thanks so much for the reply! Here is a snip of my business rule, which is before insert and update. I just crossed out the Google key. In the logs, I see two warning messages:

org.mozilla.javascript.EcmaError: "rawOffset" is not defined.
Caused by error in sys_script.2733261397a20110899fbbc3f153af74.script at line 25

22: gs.logErr("Geocoding error: " + jsonOutput);
23: }
24: }
==> 25: })(current, previous);

and

org.mozilla.javascript.EcmaError: "rawOffset" is not defined.
Caused by error in <refname> at line 14

11: var output = new JSONParser().parse(ret);
12: if (output.status == "OK") {
13: //set the timezone - I made the field time zone, hence the underscore between the words
==> 14: current.u_time_zone = output.timeZoneId;
15: current.u_offset = output.rawOffset; //set the offset
16: } else {
17: gs.logErr("Get_Lat_Long Lookup Error: " + output.status);

Both custom time zone and offset fields do not receive any values, so that's why I thought maybe there was a coding issue in the business rule you shared.

Thank you!

Mike

 

find_real_file.png

Munender Singh
Mega Sage

Hello Mike,

Please check and share the following info:

1. Complete Response error message 

2. You must enable Billing on the Google Cloud Project at https://console.cloud.google.com/project/_/billing/enable Learn more at https://developers.google.com/maps/gmp-get-started

3. Remove 'rawOffset' in line 1 of your code

4. Please do not enclose API KEY in quotes means, it should be like &key=XXXXXX

 

Regards,

Munender

 

Mike Naputano
Tera Expert

Hi Munender,

   Removing rawOffset helped for sure, as well as removing the quotes around the google key, so thanks so much for that.

Question about the enable billing message; is there a charge for every time the rule runs?

Thanks,

Mike

Munender Singh
Mega Sage

Hello Mike,

Enable billing is free for first few days. I implemented it for the client as it was a one time load for all locations.

Regards,

Munender

 

 

 

Mike Naputano
Tera Expert

Ah OK...thanks so much for your assistance!

Mike

Version history
Last update:
‎02-18-2019 04:59 AM
Updated by: