node package manager

cogs-sdk

Unified JavaScript SDK for Cogs' APIs

A unified JavaScript SDK for the Cogs (cogswell.io) APIs

Version npm

NOTE: There are breaking changes moving from version 2.x to 3.x. Please look at the client API's subscribe function below for the new example.

This module contains the JavaScript SDKs for the various Cogs APIs.

  • Info - Informational APIs requiring no authentication.
  • Tools - Customer APIs which are meant for Cogs' users' internal use only (not client apps, websites, or devices). These require authentication using customer API key credentials.
  • Client - Client APIs which are meant for client software (apps, devices, etc.). These require authentication using derived client (salt/secret pair generated by the tools API) credentials.

Configuration

There are different configurations for the client and tools SDKs. While it is possible to include all key components (both the api key and client key) required in order to use both at the same time (and this is fine for testing on your own equipment), the secret component of your Cogs API key should never be placed into an app, a consumer device, or field unit.

An example of each type of config are included in this repository in the cogs-tools.json and cogs-client.json for the tools and client APIs respectively.

The tools SDK requires that the api_key.access and api_key.secret fields be populated.

The client SDK requires that the api_key.access, client_key.salt, and client_key.secret fields be populated.

Info API Routes

GET /api-docs

Provides the Swagger documentation for the Cogs APIs formatted as JSON.

var cogs = require('cogs-sdk');
 
cogs.info.getClient('cogs-tools.json')
.then((client) => {
  return client.getApiDocs();
})
.then((docs) => {
  console.log(`Cogs API Docs:\n${JSON.stringify(docs, null, 2)}`);
})
.catch((error) => {
  console.error(`Error fetching the Cogs API docs: ${error}\n${error.stack}`);
});

GET /build_info

Provides details regarding the currently deployed version Cogs. This information is useful when reporting issues with the service APIs.

var cogs = require('cogs-sdk');
 
cogs.info.getClient('cogs-tools.json')
.then((client) => {
  return client.getBuildInfo();
})
.then((docs) => {
  console.log(`Cogs Build Info:\n${JSON.stringify(docs, null, 2)}`);
})
.catch((error) => {
  console.error(`Error fetching the Cogs build info: ${error}\n${error.stack}`);
});

Tools API Routes

All of these routes are authenticated using the access_key and secret_key.

GET /namespace/:NAMESPACE_NAME/schema

Use this endpoint to fetch the schema for one of your namespaces. This includes the attributes for that namespace as well as all core attributes for your account. It will indicate the type of each attribute and indicate whether it is part of the primary key for that namespace.

var cogs = require('cogs-sdk');
var namespace = 'my-namespace';
 
cogs.tools.getClient('cogs-tools.json')
.then((client) => {
  return client.getNamespaceSchema(namespace);
})
.then((schema) => {
  console.log(`Schema for namespace '${namespace}':\n${JSON.stringify(schema, null, 2)}`);
})
.catch((error) => {
  console.error(`Error fetching the schema for namespace ${namespace}${error}\n${error.stack}`);
});

POST /random_uuid

Use this endpoint to generate random (version 4) UUID for use by client devices from a solid entropy source.

var cogs = require('cogs-sdk');
 
cogs.tools.getClient('cogs-tools.json')
.then((client) => {
  return client.newRandomUuid();
})
.then((uuid) => {
  console.log(`New Random UUID:\n${uuid}`);
})
.catch((error) => {
  console.error(`Error generatoring new random UUID: ${error}\n${error.stack}`);
});

POST /client_secret

Use this endpoint to generate new client keys for your client devices/apps. The new salt/secret pair will be associated with the api key you use to authenticate this API operation. When you disable (revoke) an api key, all client keys generated using that api key are also disabled.

var cogs = require('cogs-sdk');
 
cogs.tools.getClient('cogs-tools.json')
.then((client) => {
  return client.newClientKey();
})
.then((clientKey) => {
  console.log(`New Cogs Client Key:\n${JSON.stringify(docs, null, 2)}`);
})
.catch((error) => {
  console.error(`Error generating new Cogs client key: ${error}\n${error.stack}`);
});

Client API Routes

All of these routes are authenticated using the access_key, client_salt and client_secert.

POST /event

All events are sent to Cogs through this route. The event data must only contain attributes valid for the namespace specified in the request. It must also include all attributes defined as primary key attributes for the namespace. These uniquely identify the topic of the event.

var cogs = require('cogs-sdk');
 
var namespace = 'my-namespace';
var eventName = 'my-event'
var attributes = {
  'my-id-attribute': 12,
  'my-name': 'Bob',
  'my-boolean': true
};
var tags = ['foo', 'bar'];
 
cogs.cep.getClient('cogs-client.json')
.then((client) => {
  return client.sendEvent(namespace, eventName, attributes, tags);
})
.then(() => {
  console.log('Event successfully sent.');
})
.catch((error) => {
  console.error(`Error sending event: ${error}\n${error.stack}`);
});

POST /channel_summary

A summary of the most recent value for each attribute associated with a channel can be fetched via this route. This may contain values from multiple events (a event-sourced summary of the channel).

var cogs = require('cogs-sdk');
 
var namespace = 'my-namespace';
var eventName = 'my-event'
var attributes = {
  'my-id-attribute': 12
};
var tags = ['foo', 'bar'];
 
cogs.cep.getClient('cogs-client.json')
.then(client => {
  return client.getChannelSummary(namespace, attributes);
})
.then(summary => {
  console.log('Channel summary is:', summary);
})
.catch(error => {
  console.error(`Error sending event: ${error}\n${error.stack}`);
});

GET /message/:MESSAGE_ID

Messages generated by Cogs may be fetched by their ID. This is important for mobile devices which receive only the message ID in notifications and need to fetch the full message payload in response to the notification. This is also useful when for space constraints you wish to store only historical message IDs on a device, and fetch messages from Cogs only when you need to reference them. Keep in mind that the identified message is also paired with the namespace and topic attributes identified in the authentication payload.

var cogs = require('cogs-sdk');
 
var namespace = 'my-namespace';
var topicAttributes = {
    'my-id-attribute': 12
};
var messageId = 'deadbeef-dead-beef-dead-beefdeadbeef';
 
cogs.cep.getClient('cogs-client.json')
.then((client) => {
  return client.getMessage(namespace, topicAttributes, messageId);
})
.then((message) => {
  console.log(`Successfully retrieved message:\n${JSON.stringify(message, null, 2)}`);
})
.catch((error) => {
  console.error(`Error fetching message '${messageId}': ${error}\n${error.stack}`);
});

GET /push

This endpoint is use to establish WebSockets in order to receive push notifications for individual topics. New messages generated for a particular topic are delivered to all WebSockets registered with that topic's identifying attributes. Unlike mobile notifications, which only contain the message ID, the payload sent over these WebSockets is the entire message payload. It does include the message ID, so you can still fetch the message again later by its ID.

var cogs = require('cogs-sdk');
 
var namespace = 'my-namespace';
var topicAttributes = {
  'my-id-attribute': 12
};
 
cogs.cep.getClient('cogs-client.json')
.then(client => {
  return new Promise((resolve, reject) => {
    const ws = client.subscribe(namespace, topicAttributes)
    
    ws.on('error', error => {
      console.error('Error in push WebSocket', error)
 
      // The socket will either stay alive or be replaced on error, this is 
      // just to complete our example which expects a single message. 
      try {
        ws.close();
      } catch (e) {
        console.error('Websocket is already closed', error);
      } finally {
        reject(error);
      }
    });
    
    ws.on('reconnect', () => console.log('Push WebSocket replaced.'));
    ws.on('open', () => console.log('Push WebSocket established.'));
    ws.on('close', () => {
      console.log('Push WebSocket closed.')
      resolve();
    });
 
    ws.on('message', message => console.log('Received a message:', message));
    ws.on('ack', messageId => {
      console.log(`Message ${messageId} acknowledged.`);
      ws.close(); // Alias to ws.disconnect() 
    });
 
    ws.on('connectFailed', error => {
      console.error('Error upgrading GET request to WebSocket', error)
      reject(error);
    });
  });
})
.catch(error => {
  console.error(`Error establishing push WebSocket: ${error}\n${error.stack}`);
});

The cogs command line utility

This module includes a command-line utility named named cogs. You can use it in order to run the tools commands. By default it will look for a configuration file in either the current directory or your home directory named either cogswell.json or cogs.json. You can also supply the location of the config file as the last argument to any command.

If you install locally, the cogs command will be available only within that project. Installing it globally makes it available from anywhere.

List the available commands

$ cogs -h
 
  Usage: cogs [options] [command]
 
 
  Commands:
 
    key [config]                         
    client-key [config]                  
    uuid [config]                        
    random-uuid [config]                 
    schema <namespace> [config]          
    namespace-schema <namespace> [config]
    build [config]
    build-info [config]
 
  Options:
 
    -h, --help  output usage information
 

Generate a client key config file

$ cogs key
Wrote new client config to cogs-client-abababababababab.json
 
$ cat cogs-client-abababababababab.json
{
  "api_key": {
    "access": "abababababababababababababababab"
  },
  "client_key": {
    "salt": "abababababababababababababababababababababababababababababababab",
    "secret": "abababababababababababababababababababababababababababababababab"
  },
  "http_request_timeout": 30000,
  "websocket_connect_timeout": 30000,
  "websocket_auto_reconnect": true
}

Generate a random UUID

$ cogs uuid
7932ff8e-d454-4531-beac-3437c46d13fb

Describe a namespace schema

$ cogs schema auto-monitor
{
  "attributes": [
    {
      "name": "driver-door-open",
      "data_type": "Boolean",
      "core": false,
      "ciid": false
    },
    {
      "name": "hood-open",
      "data_type": "Boolean",
      "core": false,
      "ciid": false
    },
    {
      "name": "vehicle-uuid",
      "data_type": "Text",
      "core": false,
      "ciid": true
    }
  ]
}

Fetch the build info for the Cogs' API

$ cogs build-info
{
  "build_time": "2016-06-13T22:39:55+0000",
  "commit_hash": "da3d615485135b71873481282c13d30e52b16370"
}