@cesarbr/meshblu v1.34.3
node-meshblu-socket.io
A client side library for using the Meshblu Socket.IO API in Node.js
NOTICE: @cesarbr Scope
This is an updated version of the meshblu package that contains only security fixes for the unsupported v1. For the latest version, use the original package.
Table of Contents
- Getting Started
- Events
- Methods
- createConnection(options)
- conn.device(query, callback)
- conn.devices(query, callback)
- conn.generateAndStoreToken(query, callback)
- conn.message(message)
- conn.register(params, callback)
- conn.revokeToken(auth, callback)
- conn.subscribe(params)
- conn.unregister(query, callback)
- conn.unsubscribe(params)
- conn.update(query, callback)
- conn.whoami(obj, callback)
Getting Started
Install
The Meshblu client-side library is best obtained through NPM:
npm install --save @cesarbr/meshbluAlternatively, a browser version of the library is available from https://cdn.octoblu.com/js/meshblu/latest/meshblu.bundle.js. This exposes a global object on window.meshblu.
<script type="text/javascript" src="https://cdn.octoblu.com/js/meshblu/latest/meshblu.bundle.js" ></script>Quick Start
The client side library establishes a secure socket.io connection to Meshblu at https://meshblu-socket-io.octoblu.com by default.
var meshblu = require('@cesarbr/meshblu');
var conn = meshblu.createConnection({
uuid: '78159106-41ca-4022-95e8-2511695ce64c',
token: 'd5265dbc4576a88f8654a8fc2c4d46a6d7b85574'
});
conn.on('ready', function(){
console.log('Ready to rock');
});Events
Event: "config"
The config event is emitted whenever a device is updated. Use the conn.subscribe API to subscribe to config events. In order to receive config events from a device, your connection must be authenticated as a device that is in the target device's configure.sent whitelist. See the Meshblu whitelist documentation for more information.
deviceMeshblu device that was modifieduuidUuid of the device that was modified
Example
conn.on('config', function(device){
console.log('on config');
console.log(JSON.stringify(device, null, 2));
// on config
// {
// "meshblu": {
// "version": "2.0.0",
// "whitelists": {},
// "hash": "9OAPxo5Yq1oTYNi1szGVBBlg4xuIVni47k8JhHYlXFk="
// }
// },
// "uuid": "78159106-41ca-4022-95e8-2511695ce64c",
// "foo": "bar"
// }
});
otherConn.update({uuid: '78159106-41ca-4022-95e8-2511695ce64c', foo: 'bar'});Event: "message"
The message event is emitted whenever a device sends or receives a message. Use the conn.subscribe API to subscribe to message events for a device. In order to receive broadcast from a device, your connection must be authenticated as a device that is in the target device's broadcast.sent whitelist. To receive message sent by a device, your connection must be in the target's message.sent whitelist. To receive messages from other devices, they must be in the authorized device's message.from whitelist. See the Meshblu whitelist documentation for more information.
messageMessage object that was received.devicesArray of UUIDs to whom the message was sent. It will contain the string"*", If the message was a broadcast.fromUuidUuid of the device that sent the message. Is set by Meshblu, so it can be trusted as long as it is verified that the message was received through Meshblu.
Example
conn.on('message', function(message){
console.log('on message');
console.log(JSON.stringify(message, null, 2));
// on message
// {
// "devices": [
// "*"
// ],
// "foo": "bar",
// "fromUuid": "1f6d9e7b-059b-4c1a-b699-708948ad8e10"
// }
});
otherConn.message({devices: ['*'], foo: 'bar'});Event: "notReady"
The notReady event is emitted when certain things go wrong. These include emitting invalid authentication information in response to the identify challenge.
responseResponse of a failed authentication attempt.uuidUUID of the device the connection attempted to authenticated as.tokenPlain-text token of the device the connection attempted to authenticate as. Thetokenis passed through by the API so that it can be returned here, it is never stored as plain text by Meshblu.- (deprecated)
apiA legacy identifier kept for backwards compatibility. Should not be used in any new projects. - (deprecated)
statusA legacy status code kept for backwards compatibility. Should not be used in any new projects.
Example
When an incorrect identity event is rejected by Meshblu
conn.on('notReady', function(response){
console.error('notReady');
console.error(JSON.stringify(response, null, 2));
// notReady
// {
// "uuid": "i-made-this-uuid-up",
// "token": "i-made-this-token-up",
// "api": "connect",
// "status": 401
// }
});Event: "ready"
The ready event is emitted whenever the connection emits an identity and Meshblu accepts the credentials.
responseResponse of a successful authentication.uuidUUID of the device the connection is authenticated as.tokenPlain-text token of the device the connection is authenticated as. Thetokenis passed through by the API so that it can be returned here, it is never stored as plain text by Meshblu.- (deprecated)
apiA legacy identifier kept for backwards compatibility. Should not be used in any new projects. - (deprecated)
statusA legacy status code kept for backwards compatibility. Should not be used in any new projects.
Note
The "ready" event is emitted every time the connection is re-established. In normal network conditions, it is not uncommon the connection to occasionally drop and reestablish itself. In those cases, the library will re-authenticate and the brief outage will not be noticeable. Two things to note:
- Messages sent to the device while it is reconnecting will not be delivered to the client.
- Setting event listeners inside of the callback to the
"ready"event is discouraged as they will be doubled up every time the event is fired. This may lead to functions being unexpectedly called multiple times for a single event. It presents itself as erratic behavior that appears to only happen after the connection has been established for a long time, and can therefore be very difficult to track down.
Example
When a valid identity is accepted by Meshblu:
conn.on('ready', function(response){
console.log('ready');
console.log(JSON.stringify(response, null, 2));
// ready
// {
// "uuid": "78159106-41ca-4022-95e8-2511695ce64c",
// "token": "d5265dbc4576a88f8654a8fc2c4d46a6d7b85574",
// "api": "connect",
// "status": 201
// }
});Methods
createConnection(options)
Establishes a socket.io connection to meshblu and returns the connection object.
Arguments
optionsconnection options with the following keys:serverThe hostname of the Meshblu server to connect to. (Default:meshblu-socket-io.octoblu.com)portThe port of the Meshblu server to connect to. (Default:443)uuidUUID of the device to connect with.tokenToken of the device to connect with.
Note
If the uuid and token options are omitted, Meshblu will create a new device when the connection is established and emit a ready event with the device's credentials. This will be the only time that device's token is available as plain text. This auto device creation feature exists for backwards compatibility, its use in new projects is strongly discouraged.
Example
var conn = meshblu.createConnection({
server: 'meshblu-socket-io.octoblu.com'
port: 443
uuid: '78159106-41ca-4022-95e8-2511695ce64c',
token: 'd5265dbc4576a88f8654a8fc2c4d46a6d7b85574'
});conn.device(query, callback)
Retrieve a device from the Meshblu device registry by its uuid. In order to retrieve a target device, your connection must be authenticated as a device that is in the target device's discover.view whitelist. See the Meshblu whitelist documentation for more information.
Arguments
queryQuery object, must contain only theuuidproperty.uuidUUID of the device to retrieve.
callbackFunction that will be called with aresult.resultObject passed to the callback. Contains either thedeviceorerrorkey, but never both.deviceThe full device record from the Meshblu registry.errorString explaining the what went wrong. Is only present if something went wrong.
Note
In Meshblu, it is not possible to distinguish between a device not existing and not having permission to view a device. In most of the Meshblu API calls, the error in both cases yields the protocol-specific equivalent of an HTTP 404: Not Found. The Socket.IO API, however, returns the error Forbidden. This is for backwards compatibility and will likely change with the next major version release of the Socket.IO API.
Example
When requesting a valid device that the authorized device may view:
conn.device({uuid: '78159106-41ca-4022-95e8-2511695ce64c'}, function(result){
console.log('device');
console.log(JSON.stringify(result, null, 2));
// device
// {
// "device": {
// "meshblu": {
// "version": "2.0.0",
// "whitelists": {},
// "createdAt": "2016-05-19T23:28:08+00:00",
// "hash": "4ez1I/uziZVk7INf6n1un+op/oNsIDoFVs/MW/KGWMQ=",
// "updatedAt": "2016-05-20T16:07:57+00:00"
// },
// "uuid": "78159106-41ca-4022-95e8-2511695ce64c",
// "online": true
// }
// }
});When requesting a non-existing device, or a device the authenticated device may not view:
conn.device({uuid: 'i-made-this-uuid-up'}, function(result){
console.log('device');
console.log(JSON.stringify(result, null, 2));
// device
// {
// "error": "Forbidden"
// }
});conn.devices(query, callback)
Retrieve devices from the Meshblu device registry. In order to retrieve a target device, your connection must be authenticated as a device that is in the target device's discover.view whitelist. See the Meshblu whitelist documentation for more information.
Arguments
queryQuery object, filters the device that will be returned. With the exception of the following special cases, properties are used as filters. For example, passing a query of{color: 'red'}will yield all devices that contain a color key with value 'red' that the authorized connetion has access to.onlineIf present, the value foronlinewill be compared against the string "true", and the resulting boolean value will be used. Note: using a boolean value oftruewill be evaluated asfalsebecause it is not equeal to "true"."null"&""If any key is passed in with a value of the string"null"or the empty string"", it will retrieve only devices that do not contain the key at all.
callbackFunction that will be called with aresult.resultObject passed to the callback. Contains thedeviceskey.devicesThe devices retrieved from the Meshblu registry.
Example
When requesting valid devices that the authorized device may view:
conn.devices({color: 'blue'}, function(result){
console.log('devices');
console.log(JSON.stringify(result, null, 2));
// devices
// {
// "devices": [
// {
// "color": "blue",
// "discoverWhitelist": [ "*" ],
// "uuid": "c30a7506-7a45-4fe1-ab51-c57afad7f41a"
// },
// {
// "color": "blue",
// "discoverWhitelist": [ "*" ],
// "uuid": "7a9475ea-a595-42a4-8928-0aeb677c4990"
// }
// ]
// }
});When requesting a non-existing devices, or devices the authenticated device may not view:
conn.devices({color: 'i-made-this-color-up'}, function(result){
console.log('devices');
console.log(JSON.stringify(result, null, 2));
// device
// {
// "devices": []
// }
});conn.generateAndStoreToken(query, callback)
Generate a session token for a device in the Meshblu device registry. In order to generate a token, your connection must be authenticated as a device that is in the target device's configure.update whitelist. See the Meshblu whitelist documentation for more information.
Arguments
queryQuery object, must contain only theuuidproperty.uuidUUID of the device to generate a token for.
callbackFunction that will be called with aresult.resultObject passed to the callback. Contains either the (uuid,token,createdAt) triplet, orerrorkey, but never both.uuidThe uuid for which a token was generated.tokenThe token that was generated in plain-text form. This is the only time that token will ever be shown. If it is not saved at this point, it can never be retreivedcreatedAtAn ISO 8601 timestamp for when the token was generated.errorString explaining the what went wrong. Is only present if something went wrong.
Note
In Meshblu, it is not possible to distinguish between a device not existing and not having permission to view a device. In most of the Meshblu API calls, the error in both cases yields the protocol-specific equivalent of an HTTP 404: Not Found. The Socket.IO API, however, returns the error Forbidden. This is for backwards compatibility and will likely change with the next major version release of the Socket.IO API.
Example
When generateAndStoreToken is called for a valid device that the authorized device may update:
conn.generateAndStoreToken({uuid: '78159106-41ca-4022-95e8-2511695ce64c'}, function(result){
console.log('generateAndStoreToken');
console.log(JSON.stringify(result, null, 2));
// generateAndStoreToken
// {
// "uuid": "78159106-41ca-4022-95e8-2511695ce64c",
// "createdAt": "2016-05-20T18:25:13.587Z",
// "token": "8234f58b65ff042da60d84af4230d3692778ca5b"
// }
});When generateAndStoreToken is called for a non-existing devices, or devices the authenticated device may not update:
conn.generateAndStoreToken({uuid: 'i-made-this-uuid-up'}, function(result){
console.log('generateAndStoreToken');
console.log(JSON.stringify(result, null, 2));
// generateAndStoreToken
// {
// "error": "Forbidden"
// }
});conn.message(message)
Send a message to one or more Meshblu devices. In order to send a device a message, the connection must be authenticated as a device that is in the recipient's message.from whitelist. See the Meshblu whitelist documentation for more information.
Arguments
messageMessage object, must contain only thedevicesproperty.topicis treated special by Meshblu. Other properties are forwarded to the recipient(s), but Meshblu does not act on them in any way.devicesArray of UUIDs of devices to send the message to. If any of the UUIDs are the special string"*", then the message will also be emitted as abroadcastmessage, and can be picked up by anyone in the emitter'sbroadcast.sentwhitelist.topicIf the topic is provided as a string and the message is broadcast, the topic can be used by subscribers to filter incoming messages server-side.
Note
Meshblu does not currently provide any receipt confirmation natively. If a message is sent to an offline recipient that has no message forwarding or device subscriptions, the message will be dropped. If it is important to know when the recipient received a message, it is recommended to have the recipient send some form of acknowledgement message back.
Example
To send a direct message.
conn.message({
devices: ['78159106-41ca-4022-95e8-2511695ce64c'],
topic: 'greeting',
data: {
howdy: 'partner'
}
});To send a broadcast message.
conn.message({
devices: ['*'],
topic: 'exclamation',
data: {
feeling: 'good'
}
});To send a message that is simultaneously broadcast and sent directly to a device.
conn.message({
devices: ['*', '78159106-41ca-4022-95e8-2511695ce64c'],
topic: 'recommendation',
data: {
guys: '78159106-41ca-4022-95e8-2511695ce64c is a pretty awesome dude!'
}
});conn.register(params, callback)
Register a new device with the Meshblu registry.
Arguments
paramsA device object. May not include auuidortoken. All other properties will be saved to the device on creation. For a description of the properties that will affect how Meshblu interacts with the device, see the core Meshblu documentation. If auuidand/ortokenis provided, it will be ignored.callbackFunction that is called with adeviceon registrationdeviceThe newly registered Meshblu device. Make sure to save theuuidandtoken. Thetokenwill not be made available again as it is not stored in plain-text anywhere by Meshblu.
Note
The Socket.io implementation of Meshblu creates open devices using the old (deprecated) whitelists by default. This is to preserve backwards compatibility. It is strongly recommended to register devices with explicitly locked down version 2.0.0 whitelists instead by creating a v2.0.0 device (see the second example).
Example
To register a new (open) device
conn.register({color: 'black'}, function(device){
console.log('register');
console.log(JSON.stringify(device, null, 2))
// {
// "color": "black",
// "discoverWhitelist": [
// "*"
// ],
// "configureWhitelist": [
// "*"
// ],
// "sendWhitelist": [
// "*"
// ],
// "receiveWhitelist": [
// "*"
// ],
// "uuid": "5c7392dc-a4ba-4b5a-8c84-5934a3b3678b",
// "online": false,
// "token": "9e78f644a866e1b5b71d0a2dde912e8662477abf",
// "meshblu": {
// "createdAt": "2016-05-20T22:10:23+00:00",
// "hash": "kt8lmSb5r6ruHG41jqZZHp1CEQvzM1iMJ/kAUppryZo="
// }
// }
});To register a new closed device.
conn.register({color: 'black', version: '2.0.0'}, function(device){
console.log('register');
console.log(JSON.stringify(device, null, 2))
// {
// "color": "black",
// "uuid": "5c7392dc-a4ba-4b5a-8c84-5934a3b3678b",
// "online": false,
// "token": "9e78f644a866e1b5b71d0a2dde912e8662477abf",
// "meshblu": {
// "version": "2.0.0",
// "createdAt": "2016-05-20T22:10:23+00:00",
// "hash": "kt8lmSb5r6ruHG41jqZZHp1CEQvzM1iMJ/kAUppryZo="
// }
// }
});conn.revokeToken(auth, callback)
Revoke a session token for a device
Arguments
authAuthentication object, must contain only theuuidandtokenof the device to authenticate as.uuidUUID of the device to whose token to revoketokenToken of the device to revoke
callbackFunction that is called after the token has been revoked.
Example
To revoke a token for a device:
conn.revokeToken({uuid: '5c7392dc-a4ba-4b5a-8c84-5934a3b3678b', token: '9e78f644a866e1b5b71d0a2dde912e8662477abf'}, function(){
console.log('revokeToken');
});conn.subscribe(params)
Create a subscription to a device's messages. Subscribe tries to subscribe the connection to every message type. To limit subscriptions, use the types attribute.
Arguments
paramsuuidUUID of the device to subscribe to.typesArray of strings of types to subscribe to. Valid types are:broadcastbroadcast messages sent by the device and messages the device receives as a result of it being subscribed to some other device's broadcasts.receivedmessages received by the device and messages the device receives as a result of it being subscribed to some other device's received messages.sentmessages sent by the device and messages the device receives as a result of it being subscribed to some other device's sent messages.
Example
To subscribe to everything allowed for a device:
conn.subscribe({uuid: '5c7392dc-a4ba-4b5a-8c84-5934a3b3678b'});To subscribe to only broadcasts:
conn.subscribe({uuid: '5c7392dc-a4ba-4b5a-8c84-5934a3b3678b', type: ['broadcast']});conn.unregister(query, callback)
Remove a device from the Meshblu device registry. In order to unregister a target device, your connection must be authenticated as a device that is in the target device's configure.update whitelist. See the Meshblu whitelist documentation for more information.
Arguments
queryQuery object, must contain only theuuidproperty.uuidUUID of the device to unregister.
callbackFunction that will be called with aresult.resultResponse from the unregister call. Will contain either auuidor anerror, but never both.uuidUuid of the device that was unregisterederrorString explaining the what went wrong. Is only present if something went wrong.
Note
In Meshblu, it is not possible to distinguish between a device not existing and not having permission to view a device. In most of the Meshblu API calls, the error in both cases yields the protocol-specific equivalent of an HTTP 404: Not Found. The Socket.IO API, however, returns the error Forbidden. This is for backwards compatibility and will likely change with the next major version release of the Socket.IO API.
Example
When unregister is called for a device the authenticated device may modify:
conn.unregister({uuid: 'f52d8b52-ef04-44d3-ae45-59dfec2f7663'}, function(result){
console.log('unregister');
console.log(JSON.stringify(result, null, 2));
// unregister
// {
// "uuid": "f52d8b52-ef04-44d3-ae45-59dfec2f7663"
// }
});When unregister is called for a non-existing device, or device the authenticated device may modify:
conn.unregister({uuid: 'i-made-this-uuid-up'}, function(result){
console.log('unregister');
console.log(JSON.stringify(result, null, 2));
// unregister
// {
// "error": "Forbidden"
// }
});conn.unsubscribe(params)
Remove a subscription to a device's messages. Unsubscribe tries to unsubscribe the connection from every message type. To limit what is unsubscribed, use the types attribute.
Arguments
paramsuuidUUID of the device to unsubscribe from.typesArray of strings of types to unsubscribe from. Valid types are:broadcastbroadcast messages sent by the device and messages the device receives as a result of it being subscribed to some other device's broadcasts.receivedmessages received by the device and messages the device receives as a result of it being subscribed to some other device's received messages.sentmessages sent by the device and messages the device receives as a result of it being subscribed to some other device's sent messages.
Example
To unsubscribe from everything allowed for a device:
conn.subscribe({uuid: '5c7392dc-a4ba-4b5a-8c84-5934a3b3678b'});To unsubscribe from only broadcasts:
conn.subscribe({uuid: '5c7392dc-a4ba-4b5a-8c84-5934a3b3678b', type: ['broadcast']});conn.update(query/update, callback)
Update a device in the Meshblu device registry. In order to update a target device, your connection must be authenticated as a device that is in the target device's configure.update whitelist. See the Meshblu whitelist documentation for more information.
Arguments
query/updateBoth the query and update object. Must contain at least auuid. Other than the listed exceptions, all other parameters will overwrite the device in the registry.uuidUUID of the device to update. If omitted, it defaults to the UUID of the authenticated connection.
callbackFunction that will be called with aresult.resultObject passed to the callback.uuidThe uuid of the device that was updated.statusStatus code of the update operation. Will always be200, even if the update did not happen.
Example
Updating a device:
conn.update({uuid: 'c30a7506-7a45-4fe1-ab51-c57afad7f41a', color: 'blue'}, function(result){
console.log('update');
console.log(JSON.stringify(result, null, 2));
// update
// {
// "uuid": "78159106-41ca-4022-95e8-2511695ce64c",
// "status": 200
// }
});When updating a non-existing devices, or a device the authenticated connection may not update:
conn.update({uuid: 'i-made-this-uuid-up', color: 'blue'}, function(result){
console.log('update');
console.log(JSON.stringify(result, null, 2));
// update
// {
// "uuid": "i-made-this-uuid-up",
// "status": 200
// }
});conn.whoami(obj, callback)
Retrieve the device the connection is currently authenticated as from the Meshblu device registery.
Arguments
objObject. Anything may be put here, but it will be ignored. Is preserved for backwards compatibility.callbackFunction that will be called with adevice.deviceFull device from the Meshblu device registry.
Example
Calling whoami: When whoami is called:
conn.whoami({doesnt: 'matter', one: 'bit'}, function(device){
console.log('whoami');
console.log(JSON.stringify(device, null, 2));
// whoami
// {
// "meshblu": {
// "version": "2.0.0",
// "whitelists": {},
// "createdAt": "2016-05-19T23:28:08+00:00",
// "hash": "4ez1I/uziZVk7INf6n1un+op/oNsIDoFVs/MW/KGWMQ=",
// "updatedAt": "2016-05-20T16:07:57+00:00"
// },
// "uuid": "78159106-41ca-4022-95e8-2511695ce64c",
// "online": true
// }
});