Saga Documentation 0.9.434-4

Websockets

Client applications must use one of the socket.io client libraries.

let socket = socketio.connect( URL , {transports:['websocket','polling']});

Authentication

As with REST authentication, WebSockets uses JWT Tokens. After connecting to the WebSockets server, the first call must be made to the authentication event.

socket.emit('authentication', {accessToken: 'your_access_token'});
socket.on('authenticated',  ()=> {
  //application logic
});
socket.on('unauthorized', console.log.bind(console));
//important to receive
socket.on('error', console.error.bind(console));
socket.on('disconnect', console.error.bind(console));

Success and Error Reporting

Any message send to the socket is acknowledged with an ack response. Every response contains a status_code. Any further details are provided in the body of the response. It's crucial to handle the response body to avoid any unexpected behaviour.

Javascript Example

socket.emit("/users/join", '85366adc-5be5-4b39-8164-94685840ee97',response=>{
  
  if(response.status_code === 200){
    // deal with response or ignore
  } else {
    console.error(response.body)
    // decide how to deal with it
  }
  
})

The status_code as well as the error details are identical to the ones used for HTTP Calls. See REST Success and Error Responses

Leave and Join

Through the below .../join commands an app subscribes to specific changes in saga. Each .../join is accompanied by a .../leave to unsubscribe. So for example there is /users/join and there is /users/leave. The leave methods are not documented in detail as they always follow pattern described here.

External Resources

Geared towards apps facilitating communication between users/bots and saga.

Join User

Joining a users channel will provide real time property updates as well message updates. The message name is /users/join, the payload the user id. Note that the authenticated user requires proper permissions.

Javascript Example

socket.emit("/users/join", "id of the user",response=>{
  //handle reponse
})

Properties

Property changes are sent to /properties. Property structure:

  • type - either bot/user
  • parent_id - the id of the parent
  • name - the name of the property
  • value - the value of the property
  • sortable_id - each value has its own sortable id that can be used for streaming and history, see resources below
  • source_creator - always contains type to represent what action created that value, can be either _defaults, job, scripts, rest, socket or OOB. In case of job or script it also contains an id attribute that refers to entity that created the value
  • source_property - only if the property was created within a script the source_property with the property id is given.
  • runnable_call - the id of the runnable_call that created that property

Javascript Example

socket.on("/properties",  property=>{
  //handle reponse
})

Signals

Signals are sent to /signals. Signal structure:

  • parent_type - either bot/user/globals
  • parent_id - the id of the parent
  • name - the name of the signal
  • value - the value of the signal
  • runnable_call_id - the id of the runnable call that created that property
  • source_creator - always contains type to represent what action created that value, can be either _defaults, job, scripts, rest, socket or OOB. In case of job or script it also contains an id attribute that refers to entity that created the value

Javascript Example

socket.on("/signals",  signal=>{
  //handle reponse
})

Messages

Messages from the user are sent to /messages/outgoing, and messages to the user are sent to /messages/incoming. Message structure:

  • user_id - the id of the user
  • user - contains the username and displayname
  • bot_id - the id of the bot
  • bot - contains the name
  • body - message body
  • from - sender of the message, either bot or user
  • source_creator - the creator of the message
    • type - either 'jobs', 'scripts', 'rest' or 'socket'
    • id - the id of the script or job if that is the type
  • runnable_call_id - the runnable_call_id assoicated with the script or job
  • attachments - contains url,mime_type tuples

Javascript Example

socket.on("/messages/outgoing", "id of the user", message=>{
  //handle reponse
})

Join Bot

Joining a bot channel will provide real time property updates as well message updates. The message name is /bots/join, the payload the bot id. Note that the authenticated user requires proper permissions.

Javascript Example

socket.emit("/bots/join", "id of the bot",response=>{
  //handle reponse
})

Properties

Property changes are sent to /properties. Property structure:

  • type - either bot/user
  • parent_id - the id of the parent
  • name - the name of the property
  • value - the value of the property
  • sortable_id - each value has its own sortable id that can be used for streaming and history, see resources below
  • source_creator - always contains type to represent what action created that value, can be either _defaults, job, scripts, rest, socket or OOB. In case of job or script it also contains an id attribute that refers to entity that created the value
  • runnable_call_id - only if the property was created within a script the source_property with the property id is given.
  • "runnable_call - the id of the runnable_call that created that property

Javascript Example

socket.on("/properties",  property=>{
  //handle property
})

Messages

Messages from the bot are sent to /messages/outgoing, and messages to the bot are sent to /messages/incoming. Message structure:

  • user_id - the id of the user
  • user - contains the username and displayname
  • bot_id - the id of the bot
  • bot - contains the name
  • body - message body
  • from - sender of the message, either bot or user
  • source_creator - the creator of the message
    • type - either 'jobs', 'scripts', 'rest' or 'socket'
    • id - the id of the script or job if that is the type
  • runnable_call_id - the runnable_call_id associated with the script or job
  • attachments - contains url,mime_type tuples

Javascript Example

socket.on("/messages/incoming",  message=>{
  //handle message
})

Join Globals

Joining a bot channel will provide real time property updates. The message name is /globals/join. Note that the authenticated user requires proper permissions.

Javascript Example

socket.emit("/globals/join",response=>{
  //handle reponse
})

Properties

Property changes are sent to /properties. Property structure:

  • type - either bot/user
  • parent_id - the id of the parent
  • name - the name of the property
  • value - the value of the property
  • sortable_id - each value has its own sortable id that can be used for streaming and history, see resources below
  • source_creator - always contains type to represent what action created that value, can be either _defaults, job, scripts, rest, socket or OOB. In case of job or script it also contains an id attribute that refers to entity that created the value
  • source_property - only if the property was created within a script the source_property with the property id is given.
  • "runnable_call_id - the id of the runnable_call that created that property

Javascript Example

socket.on("/properties",  property=>{
  //handle property
})

Post User Message

A message from a user can be sent to /users/message, the payload is the actual usual message structure.

Javascript Example

socket.emit("/users/message", { body:'message', user_id:'user_id', bot_id:'bot_id'},response=>{
  
  if(response.status_code === 200){
    // deal with response or ignore
  } else {
    console.error(response.body)
    // decide how to deal with it
  }
  
})

Posting Properties

User, Bot and Global properties can be sent via sockets as well. The source_creator/type will be 'socket'. Note that the authenticated user requires proper permissions.

Possible message names:

  • /users/properties
  • /users/properties/OPERATOR
  • /bots/properties
  • /bots/properties/OPERATOR
  • /globals/properties
  • /globals/properties/OPERATOR

OPERATOR refers to the methods in the javascript api. Permitted names. Payload depends on the operation itself.

  • inrc
  • mul
  • sadd
  • rem
  • lpush
  • rpush
  • lpop
  • rpop
  • set
  • unset
  • hincr
  • hmul
  • hlpush
  • hrpush
  • hlpop
  • hrpop
  • hrem
  • hsadd

Javascript Example

socket.emit("/globals/properties", { name:'location', value: { lat:70.12312, lon: -12.23131 }},response=>{
  
  if(response.status_code === 200){
    // deal with response or ignore
  } else {
    console.error(response.body)
    // decide how to deal with it
  }
  
})

Internal Methods

Geared towards apps that provide administrative and authoring functions.

Join Scripts Runnable Calls

Provides real time updates when a script has been called. If the script_id is given the subscription is limited to the script, if no script_id is given all script calls will be sent.

Javascript Example

socket.emit("/scripts/runnable_calls/join", script_id, response=>{
  //handle reponse
})

It emits/runnable_calls messages that contain the runnable_call

Join Jobs Runnable Calls

Provides real time updates when a job has been called. If the job_id is given the subscription is limited to the script, if no job_id is given all script calls will be sent.

Javascript Example

socket.emit("/scripts/runnable_calls/join", script_id, response=>{
  //handle reponse
})

It emits/runnable_calls messages that contain the runnable_call.

Join Scripts Runnable Logs

Provides real job time logging output of console.log statements when logging is enabled for the script. Keep in mind that logs usually appear before a finished runnable call. script_id is required.

Javascript Example

socket.emit("/scripts/runnable_calls/join", script_id, response=>{
  //handle reponse
})

It emits/runnable_logs messages that contain the runnable_call.

Join Jobs Runnable Logs

Provides real job time logging output of console.log statements when logging is enabled for the job. Keep in mind that logs usually appear before a finished runnable call. job_id is required.

Javascript Example

socket.emit("/jobs/runnable_calls/join", job_id, response=>{
  //handle reponse
})

It emits/runnable_logs messages that contain the runnable_call.

Join Script Versions

Provides real time updates when a new version of a script has been saved. The script_id is required.

Javascript Example

socket.emit("/scripts/versions/join", script_id, response=>{
  //handle reponse
})

It emits/runnable_versions messages that contain new version.

Join Job Versions

Provides real time updates when a new version of a job has been saved. The job_id is required.

Javascript Example

socket.emit("/scripts/versions/join", job_id, response=>{
  //handle reponse
})

It emits/runnable_versions messages that contain new version.

Join NPM Package install updates

Provides real time updates of NPM Package install progress.

Javascript Example

socket.emit("/npm_packages/join", job_id, response=>{
  //handle reponse
})

It emits/npm_packages messages that contain updated npm package information.