Script Apps

With Apps, you can build and manage your own scripted extensions for the application.

Enabling the App Builder

1. In Site Admin, access your application privileges and features.

2. Under ScriptApp, these privileges:

Screenshot 2024-01-09 at 16.52.51.png

3. Click Save.

4. Login to the application.

5. From the main menu, go to Admin > Roles.

6. Click on the role for which you want to enable Apps.

7. Under Privileges, enable Apps in the same way you did for the application.

  • If you previously enabled Click Scripts or Web Service Scripts and had privileges for editing them enabled, you will have the _EditScriptApp privilege enabled automatically after the upgrade. 

Accessing the App Builder

The App Builder is available under Admin > Development > App Builder menu option.

Clicking it will take you to a list of existing Apps.

Click Scripts and Web Service Scripts are inside an App for each of the existing scripts. 

Screenshot 2024-01-09 at 16.55.45.png

Creating a new App

1. Click on + App to create a new App.

2. Specify a name for the new app and assign some roles to it.

These roles determine which actions are permitted to the Click Scripts in this App.

Screenshot 2024-01-09 at 16.56.37.png

3. Click Save to save the App and move on to adding scripts to it.

  • Apps for old Click / Web Service Scripts will have one script in the corresponding list. These scripts will run as before.
  • Creating a new App with a single script allows you to work with Click / Web Service Scripts as before.
  • Apps make these scripts easier to manage by enabling you to group the scripts by functionality.
  • If several scripts are needed to achieve a specific goal, they can be created in the same App. Scripts in the same App may also interact. You can see how in the following example.

Example: send a command to users once per day

In this example, we want to send a particular command to a particular group of users once per day.

Let us assume that the command is named “HelloCommand” and the relevant users are in a Tag called “Relevant Users”.

First, we will create an App called “ExampleApp” and assign it _Administrator role.

Now add a Click Script named SendCommandOnTimer. Choose Timer kind, and specify the time of the first run. If hours/minutes/seconds fields are left at 0, this script will run once per day at the specified time.

Screenshot 2024-01-09 at 17.23.00.png

Edit the script to:

// get users from RelevantUsers tag
var uids = tags.getTagByName('RelevantUsers').userIDs;
for (var i = 0; i < uids.length; i++) {
  var uid = uids[ i ];
  // find device
  var devs = directory.getDevices(uid);
  if (devs.length > 0) {
        // send command
    commands.send(devs[0].id, 'HelloCommand');

Now save the script and we’re done - at 5 PM, the script will send a command to all connected devices.


The command from the above example could also be sent manually by an operator. What if we wanted to skip the vehicles that already received the command sent by the operator when we send it from the script? In the App from the above example, create another Timer Click Script called “Reset”, set to run at an early time of day, e.g. 3:00 AM, that only does this:

// fill the app.state object with the array of relevant users
app.setState({ userIDs: tags.getTagByName('RelevantUsers').userIDs });

  Now change the “SendCommandOnTimer” script to this:

var DEFAULT_EMPTY_STATE = {userIDs: []};
// load the app.state obect
var st = app.state || DEFAULT_EMPTY_STATE;
// send command to all users in the array in the app.state
for (var i = 0; i < st.userIDs.length; i++) {
  var uid = st.userIDs[ i ];
  var devs = directory.getDevices(uid);
  if (devs.length > 0) {
    commands.send(devs[0].id, 'HelloCommand');

Now create a Command Tag called “HelloCommandTag” and add the “HelloCommand” to it. After this, create a new Command Click Script named “HelloCommandSuccess” in the ExampleApp and link it to HelloCommandTag. It should contain this script:

if (new Date().getHours() < 17) {
  // if the current time is < 5 PM
  if ( == 'HelloCommand' && click.operation == 'Completed') {
    // if command completed successfully
    // load state
    var st = app.state || {userIDs: []};
    // remove this user id from the array in the state
    for(var i = 0; i < st.userIDs.length; i++) {
      if (st.userIDs[ i ] == {
        st.userIDs.splice(i, 1);
    // update state

ExampleApp will now ensure that HelloCommand is sent from the script only to devices that have not received it yet.


Apps will be included in the VehicleTracker application template when exporting/synchronizing the application. 
You can export Apps separately, too, by using the Export context menu option of the App. 
Import them via “Import Template” option in VehicleTracker. An App will be exported together with all the objects required by the script definitions. For example, if you create a Notifier Click Script, the Event Rule that it is connected to will be exported as well. Any objects that are not automatically included, yet are needed for the scripts in the App to function correctly (such as ‘RelevantUsers’ tag accessed from a script in the example above) can be manually added to the App in the References section. 

Enable Logging at Runtime

The easiest way to see logs from your scripts is to use the App Console. Everything logged with the log() method will be displayed there. 

You may also log to a file with the log function and logging of errors from Click Scripts at runtime by editing the NLog.config file in the Franson NMEA Service folder under the GpsGate Server installation folder (if you are not hosting your own server, you may contact support for access to files). Under <targets>, you should add a new target entry like this:

<target name="TARGET_NAME" xsi:type="File" fileName="FILE_NAME" layout="${longdate} | ${message}"/>

where TARGET_NAME is an unique name for the file target and FILE_NAME is the name of the log file you wish to be created with full path to the file. Under <rules>, add an entry like this:

<logger name="NAME_OF_CLICK_SCRIPT" minlevel="Info" writeTo="TARGET_NAME"/>

where NAME_OF_CLICK_SCRIPT is the name of the click script which you want logged to the file, and TARGET_NAME is the unique name of the target you added above. Errors and data logged through log method in that Click Script will then be written to the specified file.