1. Paul Murray
  2. PowerBuilder
  3. Friday, 22 October 2021 22:33 PM UTC

Greetings All,

I am interested being able to use PowerBuilder to iterate through rows in a datawindow and make calls to Google Maps Routing Service to get drivetime and distance (numerical values (e.g. 176, not '2 hours 56 mins')) and store those values in a table.

I think Inet used to be the way to go here, but I understand that HTTPClient introduced recently might be easier to use.

I am hoping for some guidance on what things in what order I would need to do in order to accomplish this.

The resulting code will be published on CodeXchange with attribution.

Essentially, I need to iterate through 8,400 rows of data and get the drivetime (in minutes) and distance (as numerical value) and the same table where the data lives.

I am willing to put some effort into this if someone can kindly provide some guidance.

I think it goes as follows:

  1. Call Google Maps Routing function using Origin and Destination Lat/Longs to get DriveTime / Distance as values (as shown in screenshot).
  2. Parse out drivetime and mileage for each response. 
  3. Set variables in the same DW for DriveTime / Distance
  4. Update the DW.
  5. Commit;

I know it is a gross oversimplication...Sorry.

Thanks All!!

Paul

 

Accepted Answer
Daryl Foster Accepted Answer Pending Moderation
  1. Monday, 25 October 2021 02:12 AM UTC
  2. PowerBuilder
  3. # Permalink

Hi Paul,

 

Here is some self contained Powerbuilder code that will call the google distance API and parse the result to give you the distance and duration.  I've just presented here as a big block of code, but realistically you would take it and split it into at least two separate functions, one for the http call and one to parse the result. This should give you an idea about how to call the google API from Powerbuilder using Powerscript. This code was written in Powerbuilder 2019R3.

 

// This is an example of how to call the Google Directions API
// It would probably be in a function that returns the json

string ls_json
HttpClient lnv_HttpClient
integer li_rc
integer li_ResponseStatusCode = 0
string ls_ResponseBody = ''
string ls_ResponseStatusMessage = ''
string ls_url

// Hardcoded as an example, but should be build with latitude/longitude varables and API key
ls_url = 'https://maps.googleapis.com/maps/api/directions/json?origin=50.823189,6.191204&destination=50.776200,6.083800&key=AI...us'

lnv_HttpClient = Create HttpClient

lnv_HttpClient.SetRequestHeader('Accept', 'application/json')

li_rc = lnv_HttpClient.SendRequest('GET', ls_url)

if li_rc = 1 then
	// Can check these for a 200 succesful call, but they aren't used at the moment
	li_ResponseStatusCode = lnv_HttpClient.GetResponseStatusCode()
	ls_ResponseStatusMessage = lnv_HttpClient.GetResponseStatusText()

	li_rc = lnv_HttpClient.GetResponseBody(ls_json, EncodingUTF8!)

	if li_rc <> 1 then			
		MessageBox('HttpClient Error', 'Error getting response body for Request.  Return Code ' + string(li_rc))
	end if
else
	MessageBox('HttpClient Error', 'Error calling ' + ls_url + ' - Error Code ' + string(li_rc))
end if


// This is an example of how to parse the directions api json to find the duration and distance
// This example only gets the first leg of the first route, but the json can return multiple routes
// with multiple legs so that should be considered when creating the solution for real.
// It would probably be in a separate function that accepts the json from the http call
// and returns a new object with the distance and duration

string ls_error
long ll_root
jsonparser lnv_jsonparser

string ls_status
string ls_error_message
long ll_routes
long ll_route
long ll_legs
long ll_leg
long ll_distance
long ll_duration

long ll_distance_value
long ll_duration_value
string ls_distance_text
string ls_duration_text

lnv_jsonparser = create jsonparser

ls_error = lnv_jsonparser.LoadString(ls_json)

if Len(Trim(ls_error))  = 0 then
	ll_root = lnv_jsonparser.GetRootItem()
	ls_status = lnv_jsonparser.GetItemString(ll_root, 'status')
	if isNull(ls_status) then ls_status = ''

	if ls_status = 'OK' then
		ll_routes = lnv_jsonparser.GetItemArray(ll_root, 'routes')
		if ll_routes > 0 then
			// Get the first route (in real life you would probably interate through and get all routes)
			ll_route = lnv_jsonparser.GetChildItem(ll_routes, 1)
			ll_legs = lnv_jsonparser.GetItemArray(ll_route, 'legs')
			
			if ll_legs > 0 then
				// Get the first leg (in real life you would probably interate through and get all legs)
				ll_leg = lnv_jsonparser.GetChildItem(ll_legs, 1)

				ll_distance = lnv_jsonparser.GetItemObject(ll_leg, 'distance')			
				// These are the two distance values you will ultimately need/use
				ll_distance_value = lnv_jsonparser.GetItemNumber(ll_distance, 'value')
				ls_distance_text = lnv_jsonparser.GetItemString(ll_distance, 'text')

				ll_duration = lnv_jsonparser.GetItemObject(ll_leg, 'duration')
				// These are the two duration values you will ultimately need/use
				ll_duration_value = lnv_jsonparser.GetItemNumber(ll_duration, 'value')
				ls_duration_text = lnv_jsonparser.GetItemString(ll_duration, 'text')
				
				MessageBox('API Success', 'Distance = ' 	+ ls_distance_text + ' (' + string(ll_distance_value) + ')' + &
					'~r~nDuration = ' + ls_duration_text + ' (' + string(ll_duration_value) + ')')
			else
				// No legs, so some error has occurred
				MessageBox('API Error', 'Error calling the API.  No legs returned.')
			end if
		else
			// No routes, so some error has occurred
			MessageBox('API Error', 'Error calling the API.  No routes returned.')
		end if
	else
		// We didn't get an OK status, so something went wrong
		ls_error_message = lnv_jsonparser.GetItemString(ll_root, 'error_message')
		if isNull(ls_error_message) then ls_error_message = ''
		MessageBox('API Error', 'Error calling the API.  Return Status = ' + ls_status + '~r~nError Message: ' + ls_error_message)
	end if
else
	MessageBox('Parse Error', 'Failed to load error json ' + ls_error)
end if

Comment
  1. Daryl Foster
  2. Wednesday, 27 October 2021 01:40 AM UTC
No worries Paul. Glad to help.
  1. Helpful 1
  1. John Fauss
  2. Wednesday, 27 October 2021 14:43 PM UTC
Nicely done, Daryl - Thank you for helping Paul!

Paul, as the owner of this thread would you please mark this issue as resolved? Thanks.
  1. Helpful 1
There are no comments made yet.
Paul Murray Accepted Answer Pending Moderation
  1. Tuesday, 9 November 2021 18:11 PM UTC
  2. PowerBuilder
  3. # 1

Thanks to help from Daryl Foster, I completed this project and posted it to CodeXchange entitled 'PowerBuilder - Google Maps Distance API Example - Plus Spatial Query'.  I just posted it, so it may take some time to get past moderator review...

It includes the complete PowerBuilder project.  The PDF file includes the code to create the tables and the stored procedure.  The data_file.zip includes the data that I used which is widely available for free on the internet.

I may have moved some instance variables into global variables.  Sorry.

I hope this helps someone.

Best,

Paul

Comment
  1. Chris Pollach @Appeon
  2. Tuesday, 9 November 2021 19:15 PM UTC
Awesome .. thanks Paul!
  1. Helpful 1
  1. Armeen Mazda @Appeon
  2. Tuesday, 9 November 2021 20:38 PM UTC
Thanks for sharing the code!
  1. Helpful 1
  1. John Fauss
  2. Tuesday, 9 November 2021 22:02 PM UTC
Thank you, Paul... I look forward to seeing you back here soon!
  1. Helpful
There are no comments made yet.
Daryl Foster Accepted Answer Pending Moderation
  1. Saturday, 23 October 2021 02:53 AM UTC
  2. PowerBuilder
  3. # 2

Hi Paul, if the API that Chris has linked to is the correct one (and I think it is) then it looks like it is just a simple http call to get the data.  HttpClient would be perfect for it.  That API can work on a matrix, but since you are looking for point to point distances I think you would need to make a single call for each origin and destination.  The API returns the JSON and you'd just have to parse that to get the distance and time. If you look at the API it has some notes about the accuracy of distance and time when using latitude/longitude because the calculations are taken from the road nearest to those coordinates. But I think it should probably be ok.

The first step is to see if you can call the API in a Web Browser (Edge, Firefox or Chrome). I haven't got an API key so I can't test it, but can you see what you get when you enter the below url in a browser (replacing YOUR_API_KEY with your API key). Hopefully it should work and return JSON.  If it does then it should be pretty straight forward to write some starter code for calling it from Powerbuilder.

Here is a URL to try based on the first row of your table:

 

https://maps.googleapis.com/maps/api/distancematrix/json?destinations=50.776200%2C6.083800&origins=50.823189%2C6.191204&key=YOUR_API_KEY

 

Comment
  1. Paul Murray
  2. Sunday, 24 October 2021 22:16 PM UTC
Thanks Daryl and Mike,



I am able to use the Directions google API to get distance and drive time with this URL and my Google Maps API. The resulting JSON is below...



I will check out the links provided by Mike and report back. Hopefully there might be some vimeo or YouTube videos that act as explainers.



Best,



Paul



https://maps.googleapis.com/maps/api/directions/json?origin=50.823189,6.191204&destination=50.776200,6.083800&key=AI...us



{

"geocoded_waypoints" : [

{

"geocoder_status" : "OK",

"place_id" : "ChIJRTcQT6GfwEcRSnWuzylJk1c",

"types" : [ "premise" ]

},

{

"geocoder_status" : "OK",

"place_id" : "ChIJQbw4XHuZwEcR8SI-HP7bGB8",

"types" : [ "street_address" ]

}

],

"routes" : [

{

"bounds" : {

"northeast" : {

"lat" : 50.82603229999999,

"lng" : 6.192701100000001

},

"southwest" : {

"lat" : 50.77479959999999,

"lng" : 6.0850316

}

},

"copyrights" : "Map data ©2021 GeoBasis-DE/BKG (©2009)",

"legs" : [

{

"distance" : {

"text" : "10.9 km",

"value" : 10938

},

"duration" : {

"text" : "17 mins",

"value" : 1005

},

"end_address" : "Markt 40, 52062 Aachen, Germany",

"end_location" : {

"lat" : 50.7763237,

"lng" : 6.0850316

},

"start_address" : "Merzbrück 218, 52146 Würselen, Germany",

"start_location" : {

"lat" : 50.8232126,

"lng" : 6.192355399999999

},

"steps" : [

{

"distance" : {

"text" : "0.1 km",

"value" : 141

},

"duration" : {

"text" : "1 min",

"value" : 23

},

"end_location" : {

"lat" : 50.8244614,

"lng" : 6.192701100000001

},

"html_instructions" : "Head \u003cb\u003enorth\u003c/b\u003e toward \u003cb\u003eEschweilerstraße\u003c/b\u003e",

"polyline" : {

"points" : "aleuHgmxd@C@YAGA_@G]Ic@KOCu@Sk@K"

},

"start_location" : {

"lat" : 50.8232126,

"lng" : 6.192355399999999

},

"travel_mode" : "DRIVING"

},

{

"distance" : {

"text" : "0.8 km",

"value" : 847

},

"duration" : {

"text" : "1 min",

"value" : 64

},

"end_location" : {

"lat" : 50.8256606,

"lng" : 6.1807946

},

"html_instructions" : "Turn \u003cb\u003eleft\u003c/b\u003e onto \u003cb\u003eEschweilerstraße\u003c/b\u003e",

"maneuver" : "turn-left",

"polyline" : {

"points" : "{seuHkoxd@Cj@Eb@MnCKzBq@pN[rGQpDc@pJWjFU`FCd@C\\G^ItC"

},

"start_location" : {

"lat" : 50.8244614,

"lng" : 6.192701100000001

},

"travel_mode" : "DRIVING"

},

{

"distance" : {

"text" : "0.3 km",

"value" : 252

},

"duration" : {

"text" : "1 min",

"value" : 34

},

"end_location" : {

"lat" : 50.82603229999999,

"lng" : 6.1773924

},

"html_instructions" : "At the roundabout, take the \u003cb\u003e2nd\u003c/b\u003e exit and stay on \u003cb\u003eEschweilerstraße\u003c/b\u003e",

"maneuver" : "roundabout-right",

"polyline" : {

"points" : "k{euH}dvd@E@CBCBCDCDCDAFADAF?BAB?@?B?B?@?B?@?F?D@F@D@D@D@D@BCx@Cp@AFGfBABEz@?NCXCl@MdCCn@"

},

"start_location" : {

"lat" : 50.8256606,

"lng" : 6.1807946

},

"travel_mode" : "DRIVING"

},

{

"distance" : {

"text" : "1.8 km",

"value" : 1782

},

"duration" : {

"text" : "2 mins",

"value" : 93

},

"end_location" : {

"lat" : 50.8105014,

"lng" : 6.1716412

},

"html_instructions" : "Turn \u003cb\u003eleft\u003c/b\u003e to merge onto \u003cb\u003eA44\u003c/b\u003e toward \u003cb\u003eU18\u003c/b\u003e/\u003cwbr/\u003e\u003cb\u003eBrüssel\u003c/b\u003e/\u003cwbr/\u003e\u003cb\u003eA4\u003c/b\u003e/\u003cwbr/\u003e\u003cb\u003eAntwerpen\u003c/b\u003e/\u003cwbr/\u003e\u003cb\u003eAachen\u003c/b\u003e",

"maneuver" : "ramp-left",

"polyline" : {

"points" : "u}euHuoud@J@\\Dd@DpCd@`BXPDNBNDXJl@Vn@ZbCvAz@f@z@d@t@^z@b@TLNF^D^PTLVJXNb@RNFp@ZXJXLp@XHDXJFBB@B@JBFDVJLDh@RTH^LXJ\\Lt@TNFf@Nv@Vv@RXJZHv@Tx@PTFj@NRDn@NNB^HRDJBd@JRBRDNBHBPD@?`@Fb@HbANbAN`@F`@F^Dd@FH@|C\\TBTBr@Hf@Dl@H\\DxCZ"

},

"start_location" : {

"lat" : 50.82603229999999,

"lng" : 6.1773924

},

"travel_mode" : "DRIVING"

},

{

"distance" : {

"text" : "1.1 km",

"value" : 1073

},

"duration" : {

"text" : "1 min",

"value" : 46

},

"end_location" : {

"lat" : 50.8048291,

"lng" : 6.162407399999999

},

"html_instructions" : "Take the \u003cb\u003eA544\u003c/b\u003e exit toward \u003cb\u003eEuropapl.\u003c/b\u003e/\u003cwbr/\u003e\u003cb\u003eWürselen\u003c/b\u003e",

"maneuver" : "ramp-right",

"polyline" : {

"points" : "s|buHwktd@LLFDD@d@Jl@LVFvAXRB^BtALjCZp@HnATd@Ll@Xp@`@RPVV|@pAJRXh@LXPb@\\t@HR@@N\\j@|ARz@J~@BZFv@?\\@^?`B?@Av@?@AnB?dB@p@?RBv@?\\HjBHdBTvC"

},

"start_location" : {

"lat" : 50.8105014,

"lng" : 6.1716412

},

"travel_mode" : "DRIVING"

},

{

"distance" : {

"text" : "4.8 km",

"value" : 4832

},

"duration" : {

"text" : "4 mins",

"value" : 219

},

"end_location" : {

"lat" : 50.78078850000001,

"lng" : 6.1085406

},

"html_instructions" : "Keep \u003cb\u003eright\u003c/b\u003e at the fork, follow signs for \u003cb\u003eA544\u003c/b\u003e and merge onto \u003cb\u003eA544\u003c/b\u003e",

"maneuver" : "fork-right",

"polyline" : {

"points" : "eyauHarrd@Dd@ZzD@LDj@\\nDP|BFf@LjA@LFVFXDRFP?@BHBFHVFLHRDNDFJNFHPZRXb@j@`@j@@@TZBDT\\Vd@Xj@DDfB|F`@tATx@h@hBfAtDX`Ad@~APn@HXb@zAJZRn@DNBJL`@L`@BJb@zAv@fCPh@d@|Af@fB@DPh@n@xBDLBLL\\BL^nADLLb@J\\DLHV^rAVr@Vx@\\`ADLd@nAHVVj@\\~@HRHNHRHTDJBDFNd@`ANZHN@DBDHRbAjBv@tA^n@`BjC|AdC@Bx@rAT\\hBxCt@lAZb@NVXf@LPJPPXNTPVzAdCz@rAxA`CNVPVp@dAp@dAT`@V`@z@rAl@~@BD|@tAR\\T\\z@vAV^LRLRLRNTj@|@Zf@V`@T^`CvDZh@\\h@d@t@`@p@Zd@`BhCDHJPRZt@jA\\j@V^r@lARXLRnApB?@V`@h@z@x@pANTFHT^PXfAdBR\\JPLP@@V`@\\j@T`@h@~@JNLTVf@Rb@Vh@Tf@Tf@Rh@JZDJPd@BH@DN`@Ph@Nj@HVFVNh@Lf@Nn@Nt@Np@Hf@Hd@Ln@BPD^Lz@Hl@Hp@@FDh@Fp@Fp@Dh@@HDx@BZ@JD|@@b@Bz@@j@@p@@`@?zBCrHAr@?b@?`@@~AAhB?H?XEdCAHAP?@AJCFAFCDGJGHCFCDEX"

},

"start_location" : {

"lat" : 50.8048291,

"lng" : 6.162407399999999

},

"travel_mode" : "DRIVING"

},

{

"distance" : {

"text" : "1.1 km",

"value" : 1089

},

"duration" : {

"text" : "4 mins",

"value" : 214

},

"end_location" : {

"lat" : 50.7783703,

"lng" : 6.0944248

},

"html_instructions" : "At the roundabout, take the \u003cb\u003e2nd\u003c/b\u003e exit onto \u003cb\u003eB1\u003c/b\u003e",

"maneuver" : "roundabout-right",

"polyline" : {

"points" : "}b}tHkahd@EJEJEPAHCJAN?L?N@N@PFZFTFNBJFJHJFLDFBBHB\\RFFDHDF@@BHDPBTB`@HlALnBN|BBf@Dl@Br@@Z?N@R?r@C|@IbFClCCl@?^Cv@AF?DADADI\\DJb@hALZFLDHFLNXDHRb@LZTj@DLNb@Jb@J\\Jf@BJBN@JFf@BZHv@D`@Fv@JbALtATfCPfBRzB"

},

"start_location" : {

"lat" : 50.78078850000001,

"lng" : 6.1085406

},

"travel_mode" : "DRIVING"

},

{

"distance" : {

"text" : "0.6 km",

"value" : 625

},

"duration" : {

"text" : "3 mins",

"value" : 209

},

"end_location" : {

"lat" : 50.7748417,

"lng" : 6.087884499999999

},

"html_instructions" : "Continue straight onto \u003cb\u003ePeterstraße\u003c/b\u003e",

"maneuver" : "straight",

"polyline" : {

"points" : "ys|tHcied@DZH`@F\\l@rCF^L~@Fj@DZBTDT@F@LDPDRFRJZRn@JNDFF?JTZj@HNXf@hBfDDLn@jAb@t@f@v@l@z@HLJJFFPNd@\\NLZRRJ"

},

"start_location" : {

"lat" : 50.7783703,

"lng" : 6.0944248

},

"travel_mode" : "DRIVING"

},

{

"distance" : {

"text" : "0.1 km",

"value" : 107

},

"duration" : {

"text" : "1 min",

"value" : 34

},

"end_location" : {

"lat" : 50.7748904,

"lng" : 6.086384

},

"html_instructions" : "\u003cb\u003ePeterstraße\u003c/b\u003e turns \u003cb\u003eright\u003c/b\u003e and becomes \u003cb\u003eUrsulinerstraße\u003c/b\u003e",

"polyline" : {

"points" : "w}{tHg`dd@Bv@?BBz@KzBEv@"

},

"start_location" : {

"lat" : 50.7748417,

"lng" : 6.087884499999999

},

"travel_mode" : "DRIVING"

},

{

"distance" : {

"text" : "90 m",

"value" : 90

},

"duration" : {

"text" : "1 min",

"value" : 29

},

"end_location" : {

"lat" : 50.7756441,

"lng" : 6.0859635

},

"html_instructions" : "\u003cb\u003eUrsulinerstraße\u003c/b\u003e turns \u003cb\u003eright\u003c/b\u003e and becomes \u003cb\u003eBuchkremerstraße\u003c/b\u003e",

"polyline" : {

"points" : "a~{tH{vcd@KNGFOHOLUJE@c@J?@a@F"

},

"start_location" : {

"lat" : 50.7748904,

"lng" : 6.086384

},

"travel_mode" : "DRIVING"

},

{

"distance" : {

"text" : "0.1 km",

"value" : 100

},

"duration" : {

"text" : "1 min",

"value" : 40

},

"end_location" : {

"lat" : 50.7763237,

"lng" : 6.0850316

},

"html_instructions" : "Continue onto \u003cb\u003eBüchel\u003c/b\u003e",

"polyline" : {

"points" : "wb|tHgtcd@GDA@GFILA@KNCD[b@QXORGLEHMX"

},

"start_location" : {

"lat" : 50.7756441,

"lng" : 6.0859635

},

"travel_mode" : "DRIVING"

}

],

"traffic_speed_entry" : [],

"via_waypoint" : []

}

],

"overview_polyline" : {

"points" : "aleuHgmxd@]?g@IgCm@k@KCj@SrDkBr`@uAdZK|@ItCE@GFGJIZAXBZFT]dIQrDCn@J@bAJrF~@jAZ|Ar@~D~BbEvBNF^Dt@^dBv@vCnA~An@jFhBpDfAbDx@dFhAzCh@jEn@lFl@fCVjANxCZLLLFrAXnB`@r@F`Fh@`C^rAf@dAr@tAhBd@|@fAfCP^j@|ARz@NzAFv@?\\@`CAx@?hGLtE^|F`@`Fv@fJTrBHd@T`AXv@Nb@PVXd@v@dA|@nAlAtBhEvNxCfKrB`H~AnFv@fCh@lBjA~Dv@hCh@fBlBbGhCxG|AjDhCzE`FdIbInM`IlMvNfUva@np@pCtEdApBvAbDf@vAr@|Bn@`Cx@~D`@fCb@bDZvDLjBLhEBrACnL?xEGrGEh@Q`@KPI^KVGZEx@B`@Np@JZPVLTLFd@ZJPDJHf@j@|INdDAtCQ~LGjAKb@h@tAb@`Av@bBZx@ZfA^`B~@zJ`AfKP~@t@rD^|CN|@l@rBPVF?JTd@z@bCnEt@xAjAlBv@hARRbBnARJBv@B~@QrDSV_@V[Lc@La@FGDIHILm@z@i@z@Sb@"

},

"summary" : "A544",

"warnings" : [],

"waypoint_order" : []

}

],

"status" : "OK"

}
  1. Helpful
  1. Daryl Foster
  2. Sunday, 24 October 2021 22:26 PM UTC
Hi Paul,



Do you want the directions or just the distances between two points? If you just need the distance between two points the distancematrix api looks like it may be much simpler to parse the return. Did you want to try this link and see what the return is compared to the directions api:



https://maps.googleapis.com/maps/api/distancematrix/json?destinations=50.776200%2C6.083800&origins=50.823189%2C6.191204&key=YOUR_API_KEY
  1. Helpful
  1. Daryl Foster
  2. Monday, 25 October 2021 02:16 AM UTC
Hi Paul, see my reply above. I've posted some code that will let you call the API and parse the return json. You can just update the url in the code with one that contains your API key and it should work, giving you a message box with the distance and duration. Hopefully you can use this as the basis for creating a NVO that will call the API.



Calling the distance matrix api works exactly the same, but the json parsing would need to be specific to that api. The json parsing would be very similar though.
  1. Helpful
There are no comments made yet.
Chris Pollach @Appeon Accepted Answer Pending Moderation
  1. Friday, 22 October 2021 22:56 PM UTC
  2. PowerBuilder
  3. # 3

Hi Paul;

   I'm wondering if using the new PB built-in Web Control that allows your App to inject, execute & get results from JavaScript might be one way to approach this?

FYI: https://developers.google.com/maps/documentation/distance-matrix/overview

Food for thought.

Regards ... Chris

Comment
  1. Paul Murray
  2. Sunday, 24 October 2021 21:15 PM UTC
Thanks Chris,



The Distance Matrix is particularly useful if a meeting event coordinator wants to get the distance and time to arrival (ETA) for 50 vehicles that are on their way to pick people up or drop people off as it is many points to one point.



Does this new PB built-in Web Control have a name or a link to a video that explains how it is used?



Thank you, Sir.



Paul
  1. Helpful
  1. Chris Pollach @Appeon
  2. Sunday, 24 October 2021 22:20 PM UTC
Hi Paul;

The key is the EvaluateJavaScript command. You can see an example here:

https://youtu.be/ig_aTe5eb6U

HTH

Regards ... Chris
  1. Helpful
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.