Quickstart

For any Point of Sale (POS) integration which is the typical integrator for Table Tracker (TT), orders are the core part of TT. Here we list out some common steps when integrating with TT.

1. Discovery

The TT gateway is meant to be connected and discovered over a local network within a site. The gateway uses a discovery implementation of Apple's Bonjour. When connected, the gateway will broadcast itself with tag _tracker-http._tcp.

An application integrating with TT should listen and respond when finding the IP address of the gateway. In a DHCP network, it may be necessary to restart the search as the IP address of the gateway could change upon a shutdown.

If you are building a web application, there is no easy way to initiate a discovery (as of yet). More than likely, a discovery request has to be made outside and then passed into your application. For some common network discovery/bonjour libraries, here are just some of the example libraries that can be used to find the gateway:

Android (NSD): https://developer.android.com/training/connect-devices-wirelessly/nsd.html
iOS (Bonjour): https://developer.apple.com/bonjour/
NodeJS (MDNS): http://agnat.github.io/node_mdns/index.html
Python: https://pypi.python.org/pypi/pybonjour, https://github.com/jstasiak/python-zeroconf

2. Token Generation

See API Token Generation for more details.

With V2, token generation is much easier with just one button press of the gateway. Depending on your setup and implementation, it might only be necessary to generate one token for use with all clients within a customer site. Alternatively, pushing the gateway button might be a setup for the customer to initiate your solution on their site.

Either way, the button on the gateway should be pressed quickly to start a time window for generating the token. Once pressed, an application will have 2 minutes to request for a token before the time window expires.

An application should call GET [IP_ADDRESS]:8000/api/v2/accesstoken/generate to generate a token where [IP_ADDRESS] is the IP found in the discovery step or from your router's client list.

📘

Port

For any requests, the port should be 8000 appended to the [IP_ADDRESS] with a colon (:) (e.g. 192.168.1.23:8000)

An application could poll this endpoint until it receives a successful response from the gateway. You should receive a JSON payload with the token to use in [SECURED] requests.

{
  "status": 201,
  "token": {
    "name": "default",
    "token": "2f1f4339c7b77fa3474bf8ba8852349273e928bb8ad9d186",
    "creation_date": "2016-12-24T08:04:34",
    "last_used": null,
    "ip_address": null
  }
}

📘

Make sure the gateway is online!

For a customer-facing solution, it should be noted whether the gateway is offline or online. For a quick check without worrying about authentication, call GET [IP_ADDRESS]:8000/api/v2 to see if your receive a JSON response. If you receive a connection timeout or socket error, then it might be indicative that the gateway is not really connected to the network or that it is offline.

It is important to note that it is the responsibility of the application to store the token as the gateway will not show the token again.

3. Retrieving Active Orders

The next step once provided the token is to retrieve the active orders. We recommend connecting to WebSocket for receiving active orders and notifications. With WebSockets, it is possible to write a web application or use a WebSocket library that is available for your language of choice.

As an example of connection, we will use the Javascript WebSocket API to connect. Depending on platform and library, the syntax and calls may differ, but the common WebSocket hooks (open, close, onmessage, onerror) should be similar.

// Replace [IP_ADDRESS] with gateway IP address found during discovery.
var ws = new WebSocket("ws://[IP_ADDRESS]:8000/api/v2/websocket");

Note how the protocol has changed from http to ws. There is also no way to provide the token while connecting. Some libraries might support an Authorization header during the WebSocket handshake phase, but in cases it doesn't, we offer an alternate way of authenticating.

// Orders
var orders = {};

// Add hooks
ws.onopen = function() {
  // WebSocket connection opened, so we need to pass the token.
  // Data sent should be in JSON format.
  ws.send(JSON.stringify({ "accesstoken": "[YOUR TOKEN]"});
}

ws.onmessage = function(msg) {
  // Messages received will always be in JSON and should be parsed.
  var notification = JSON.parse(msg);
  
    // Check for notification type.
    if (notification.type === "ACTIVE_ORDERS") {
      // Handle initial population of orders
      notification.items.foreach(function(order) {
        orders.push(order);
      });
    }
    else if (notification.type === "ORDER_CREATED") {
      orders.push(order);
    }
    else if (notification.type === "ORDER_MODIFIED") {
      // Find where order is in array
      var index = orders.findIndex(function(order) {
        return order.uuid === data.uuid;
      });
      
      // Replace order
      orders.splice(index, 1, notification);
    }
    else if (notification.type === "ORDER_PAGED") {
      // Same as ORDER_MODIFIED, but allows some
      // distinguishing when an order is paged and not
      // simply some state change.
    }
}

ws.onclose = function(event) {
  // Handle close events.
}

ws.onerror = function(event) {
  // Handle errors. Perhaps attempting to reconnect?
}

When a WebSocket connection is opened by a client and no Authorization header is passed during the handshake phase, the client is expected to pass the token in a JSON payload upon openING.

{"accesstoken": "[TOKEN]"}

The client has 20 seconds to pass the token before the WebSocket connection is closed. Any invalid attempt such as passing an incorrect token or passing invalid JSON will result in the connection being closed immediately by the server.

4. Retrieving Order History

See Orders for more details and examples.

An order will eventually be finished and thus, "inactive". GET /api/v2/orders can be called with a set of query parameters. These orders can then be used to provide customers with useful analytics on past orders within a certain time period. Due to memory restrictions on the gateway, orders are kept up to two weeks before they are purged. If using or providing LRSConnect integration, orders can be sent to the cloud so that bigger time window and further analytics can be viewed.