New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

layer-websdk

Package Overview
Dependencies
Maintainers
1
Versions
62
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

layer-websdk

Layer Web SDK - JavaScript library for adding chat services to your web application.

  • 2.0.1
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
6
decreased by-57.14%
Maintainers
1
Weekly downloads
 
Created
Source

Layer Web SDK

Build Status npm version

The Layer Web SDK is a JavaScript library for adding chat services to your web application. For detailed documentation, tutorials and guides please visit our Web SDK documentation.

Supported Browsers

  • IE 11 and Edge
  • Safari 7 and up
  • Chrome 42 and up
  • Firefox 40 and up

Older versions of Chrome and Firefox will likely work.

Installation

All examples below assume your using the CDN installation method; adapting instructions to other methods should be straightforward.

CDN

Simplest approach to install the Web SDK is to add the following script tag:

<script src='//cdn.layer.com/sdk/2.0/layer-websdk.min.js'></script>
  • For stricter code control, use //cdn.layer.com/sdk/2.0.0/layer-websdk.min.js instead.

All classes can then be accessed via the layer namespace:

var client = new layer.Client({
    appId: LAYER_APP_ID
});

NPM

npm install layer-websdk --save

All classes can then be accessed via the layer module:

var layer = require('layer-websdk');

var client = new layer.Client({
    appId: LAYER_APP_ID
});

From source

Download the latest SDK release Source code archive, extract the files and run the following commands from the extracted project folder:

> npm install
> grunt build

A build/ folder will be generated that contains client.min.js file.

Other build commands:

  • grunt debug: Generates build/client.debug.js which provides source-mapped files if you need to step through the Web SDK.
  • grunt docs: Generates docs/index.html which you can open to view the API documentation.
  • grunt test: Run the unit tests

About this README

This README contains everything you need to get started. But is NOT an exhaustive source of documentation. For the full documentation, or for any topics that are missing here, go to the Web SDK documentation.

Getting Started

To start using Layer's Web SDK, you need to

  1. Initialize a layer.Client
  2. Setup event handlers
  3. Connect to Layer

1. Initializing a Client

Initialize a client with your Layer Application ID which can be found in the Developer Dashboard.

var client = new layer.Client({
    appId: LAYER_APP_ID
});

2. Setup Event handlers

The client requires two event handlers to get started:

  • challenge: Performs an authentication challenge requiring your application to provide an Identity Token
  • ready: The client is authenticated and is ready for your UI
client.on('challenge', function(evt) {
    getIdentityToken(evt.nonce, function(identityToken) {
        evt.callback(identityToken);
    })
});

client.on('ready', function() {
    renderMyUI(client);
});

The following shorthand is also acceptable:

var client = new layer.Client({
    appId: LAYER_APP_ID,
    challenge: function(evt) {
        getIdentityToken(evt.nonce, function(identityToken) {
            evt.callback(identityToken);
        })
    },
    ready: function() {
        renderMyUI(client);
    }
});

getIdentityToken() is a method you provide for accessing your Identity Provider, and is covered in the Authentication section.

3. Connect to Layer

To start the client, you will call the connect method with the userId of the user you are authenticating as:

client.connect('Frodo_the_Dodo');

This call will start the authentication process. If using the layer.Client.isTrustedDevice property, it may try to restore your last Session Token and skip authentication.

Accessing Data

Data is accessed via layer.Query instances. Some notes about queries before going into details:

  • The update() method lets you change properties of the Query and then fetches updated results.
  • Results of Queries will update as new Conversations or Messages are created locally or remotely.
  • Results are accessed via the query's data property.
  • Events are triggered whenever there is a change to the query's results.
  • Queries can be used to retrieve the following types of data:
    • Conversations: model is layer.Query.Conversation
    • Messages: model is layer.Query.Message
    • Announcements: model is layer.Query.Announcement
Conversation Query
var query = client.createQuery({
    model: layer.Query.Conversation
});

query.on('change', function(evt) {
    var conversations = query.data;
    myConversationListRenderer(conversations);
});

At this time, no predicates are supported for filtering results.

Conversations can be sorted by lastMessage.sentAt or createdAt; the default sort is createdAt; only Descending sorts are supported at this time.

var query = client.createQuery({
    model: layer.Query.Conversation,
    sortBy: [{'lastMessage.sentAt': 'desc'}]
});

Improved support for sorting and predicates will ship once the Layer's Client APIs adds a Query API.

Message Query
var query = client.createQuery({
    model: layer.Query.Message,
    predicate: 'conversation.id = "layer:///conversations/uuid"'
});

query.on('change', function(evt) {
    var messages = query.data;
    myMessageListRenderer(messages);
});

The Message query only accepts a predicate/filter of the form:

 'predicate': 'conversation.id = "' + myConversation.id + '"'

Notes:

  • Single and double quotes are both supported for this predicate.
  • No sorting options are currently supported on Message queries. They are always sorted by Message position property in descending order.
Query Update

Any time you want to change properties of your query, you can call the update() method:

Page the Query:

query.update({
    paginationWindow: query.paginationWindow + 50
});

Paging the query will fire a request to the server and append additional data to the results. In this case, the next 50 results will be downloaded.

Change the Query:

query.update({
    predicate: 'conversation.id = "' + conversation.id + '"'
});

Changing the predicate:

  • clears the query's data
  • resets its paginationWindow
  • triggers a reset event
  • fires a request to the server
  • sets the data to the results from the server
  • triggers a data event

A common pattern is to use a single layer.Query bound to your MessageListView, changing the predicate as the user moves from Conversation to Conversation.

An alternate pattern of creating a new layer.Query each time the user navigates to a new Conversation also works; however, you must destroy each query when done with it:

query.destroy();
The Query Builder

There is a layer.QueryBuilder class that simplifies assembling of Queries:

var builder = QueryBuilder
  .messages()
  .forConversation(conversationOne.id)
  .paginationWindow(50);

var query = client.createQuery(builder);

query.update(builder.forConversation(conversationTwo.id));

The QueryBuilder may suit some developer styles better.

Query Results

Any change to the Query results are announced via a change event. The simplest pattern for using a change event is to grab the query's data:

query.on('change', function(evt) {
  renderCurrentMessages(query.data);
});

To get more granular details about the different types of change events and how to access just the data within the results that have changed, see the Query API.

Authentication

Authentication requires that:

  • you have set up an Identity Service
  • your client sends a request to your identity service to get an Identity Token
  • your client provides that identity token to the Layer Web SDK

Some of these concepts are explained in more detail in the Authentication Guide; concepts specific to the Layer Web SDK are described here.

Assuming that you have an Identity Provider, your javascript application will need to provide some method (getIdentityToken() in the example below) that gets the identity token.

function getIdentityToken(nonce, callback) {
    xhr({
        url: 'https://myservice.com/identity',
        method: 'POST',
        data: {
            nonce: nonce
        }
    }, function(result) {
        callback(result.identity_token);
    });
}

Presumably, before you try to initialize a Layer Client, the user has already logged into your application, and you already have a session validating who this user is for your server. Your server just needs to take this nonce and create and Identity Token.

The full sequence may look like:

var client = new layer.Client({
    appId: LAYER_APP_ID,
    isTrustedDevice: false
});

client.on('challenge', function(evt) {
    getIdentityToken(evt.nonce, function(identityToken) {
        evt.callback(identityToken);
    })
});

Note that evt.callback must be called to provide the Layer Client with the identity token and procede with authorization.

Reusing the previous Authorization?

If the client receives the isTrustedDevice property, then it will store your user's last Session Token in localStorage.

When reloading a web page, the framework will try to restore the last session. However, it will only do this if:

  1. isTrustedDevice is true
  2. A userId property is provided to the connect() method
  3. The userId property matches the userId of the last user to login
var client = new layer.Client({
    appId: LAYER_APP_ID,
    isTrustedDevice: true
});
client.connect('Frodo_the_Dodo');
  • If there is no session cached for Frodo_the_Dodo, then your challenge event handler will be called.
  • If there is a session but its expired, then your challenge event handler will be called.
  • If there is a session and its valid, then your ready event handler will be called.

Creating a Conversation

var conversation = client.createConversation({
    participants: ['Frodo_the_Dodo','Samwise_the_Brave'],
    distinct: false,
    metadata: {
        title: 'My conversation title'
    }
});

The above Conversation will not be sent to the server until you send a message with it.

Creating and Sending a Message

// Shorthand
var message = conversation.createMessage('Hello World').send();

// Complete version
var message = conversation.createMessage({
    parts: [{
        body: 'Hello World',
        mimeType: 'text/plain'
    })]
}).send({
    title: 'New Message from the World',
    text: 'The world Says "Hello World"; its a very self involved planet',
    sound: 'ding.aiff'
});

Note that creation of a Message is separate from sending it. This allows you to add additional MessageParts to your message after creating it:

var message = conversation.createMessage('Hello World');
message.addPart({
    body: 'Farewell World',
    mimeType: 'text/plain'
});
message.send();

Also note that the send method takes an optional parameter for push notifications; without that parameter there will be no new message notification for mobile device users:

message.send({
    title: 'New Message from World',
    text: 'World Says "Hello World"; its a very self involved planet',
    sound: 'ding.aiff'
});

The exact meaning of these fields, and how to use them will depend on the platform that is receiving them; please consult the IOS and Android docs for more information.

Retrieving a Conversation

A Conversation can be retrieved by ID using:

var conversation = client.getConversation('layer:///conversations/uuid');

A Conversation can be retrieved by ID from cache OR from the server if not cached using:

var conversation = client.getConversation('layer:///conversations/uuid', true);

If you need the Conversation's details to be loaded from the server, use the 'conversations:loaded' event to be notified when its ready:

var conversation = client.getConversation('layer:///conversations/uuid', true);
conversation.once('conversations:loaded', function() {
    renderMyUI(conversation);
});

The conversations:loaded event will be called immediately if its already loaded.

Retrieving a Message

A Message can be retrieved by ID using:

var Message = client.getMessage('layer:///messages/uuid');

A Message can be retrieved by ID from cache OR from the server if not cached using:

var Message = client.getMessage("layer:///messages/uuid", true);

If you need the Message's details to be loaded from the server, use the "messages:loaded" event.

var message = client.getMessage("layer:///messages/uuid", true);
message.once("messages:loaded", function() {
    renderMyUI(message);
});

The messages:loaded event will be called immediately if its already loaded.

Persistence

Options exist to cache data in the browser. All of these capabilities are protected by the isTrustedDevice property as well as the isPersistenceEnabled property. If the device is not trusted, no data will be stored. If isPersistenceEnabled is not enabled, no data will be stored in IndexedDB (Your user's Session Token will still be persisted to localStorage). But if you set both of these to true, then data can be saved.

var client = new layer.Client({
  appId: LAYER_APP_ID,
  isTrustedDevice: true,
  isPersistenceEnabled: true
});

By default, isTrustedDevice will enable the following types of data to be stored:

  • Conversations
  • Messages
  • Announcements
  • Server Requests that have not yet completed
  • The Session Token

Change Events

The Layer Web SDK provides not just a set of APIs for letting you create, retrieve and control Conversations and Messages, but also a websocket connection that keeps your objects up-to-date and in sync with everyone else. Changes, regardless of whether they are generated by websocket data or changes you have made programatically, will all result in Events being triggered.

Commonly Used Events

There are a lot of available events, but only a few that are really necessary for building applications:

  • layer.Query Events

    • change - Any change to the Query results
  • layer.Message Events:

    • messages:sent - A Message you were sending is now sent
    • messages:change - A Message property has changed
  • layer.Conversation Events:

    • conversations:sent - A Conversation has been sent to the server
    • conversations:change - A Conversation property has changed
  • layer.Client Events: Receives all of the above events as well as:

    • ready - The client is connected, authenticated and ready for use
    • challenge - The client requires an identity token
    • messages:notify - A Message has been added to the messages cache

Event Arguments

Event callbacks are called with an event argument that is an instance of layer.LayerEvent. This contains a target property identifying the object changed, along with any information about what changed. The target allows an application to write:

client.on('conversation:change', function(event) {
    var changedItem = event.target;
    alert((changedItem.toString() + ' has changed');
});

Change events get some special handling; any event name that matches 'xxxx:change' will come with a changes property containing an array of properties that have changed:

[{
  oldValue: 5,
  newValue: 10,
  property: 'unreadCount'
}]

Change events also come with a getChangesFor method for extracting all changes to a specific property:

client.on('conversation:change', function(event) {
    var changedItem = event.target;
    var participantChanges = event.getChangesFor('participants');
    var metadataChanges    = event.getChangesFor('metadata');

    participantChanges.forEach(function(change) {
        alert(changedItem.toString() + ' old value is ' + change.oldValue +
          '; new value is ' + change.newValue);
    });

    metadataChanges.forEach(function(change) {
        alert(changedItem.toString() + ' old value is ' + change.oldValue +
          '; new value is ' + change.newValue);
    });
}, this);

The Event system is built on top of the backbone.js events. This accepts:

object.on(eventName, callback, context);

object.on('eventName1 eventName2', callback, context);

object.on({
    eventName1: callback,
    eventName2: callback,
    eventName3: callback
}, context);

object.off(eventName, null, null);
object.off(null, callback, null);
object.off(null, null, context);

Websockets

The layer.Client manages a websocket connection to the server. If the connection is lost, it will attempt to reconnect when able, and will catchup on missed events. Typically, all management of this connection should be left to the Layer Web SDK. After an extended period of disconnect (> 1 day) the Client may simply refire all Queries and refresh its data instead of trying to catch up on missed events.

Testing

To run unit tests use the following command:

npm test

Contributing

Layer Web SDK is an Open Source project maintained by Layer, inc. Feedback and contributions are always welcome and the maintainers try to process patches as quickly as possible. Feel free to open up a Pull Request or Issue on Github.

Contact

Layer Web SDK was developed in San Francisco by the Layer team. If you have any technical questions or concerns about this project feel free to reach out to Layer Support.

Keywords

FAQs

Package last updated on 02 Sep 2016

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc