npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@smarterservices/twilio-sync-client

v1.0.13

Published

Client to work with the twilio sync doc

Downloads

15

Readme

SP Twilio Sync Client

This is an npm package that is a wrapper of Twilio Sync to be used by SmarterServices. It provides convenience functions for storing and setting data in the sync doc, as well as emitting custom events.

Installation

This is a private NPM package for smarterservices, so to install the dependency for your project, add this to the package.json dependencies

"@smarterservices/twilio-sync-client": "1.0.0",

Then it is a simple import to use it in react

import {TwilioSyncClient, ActionTypes} from '@smarterservices/twilio-sync-client';

As you can see, we are going to import both TwilioSyncClient and ActionTypes.

Instantiating the TwilioSyncClient

Here is a code example of how to create an instance of our TwilioSyncClient.

let twilioSyncClient;

new TwilioSyncClient({
    baseUri: `${config.apiUrl}`,
    documentId: `Student_${sessionStart.session.sid}`,
    identity: `${sessionStart.session.sid}`,
    token: `${validSpToken}`,
    initialData: syncDocInitialData
}).then((client) => {
    twilioSyncClient = client;
});

Because this client has to work with older versions of Webpack, the constructor looks a little different. In our old UI we cannot use async/await, so the client returns a version of itself as a Promise. In newer versions of react/Webpack, this instantiation can look different to wait for the Promise to resolve.

Required Fields:

  • baseUri: This is the base URI pointing to the SP API - example) 'https://api.dev.smarterproctoring.com/v1'
  • documentId: This is the unique name for the sync document.
    • For a session sync doc we do: "Session_" + sessionSid
      • ex). "Session_ES12345678901234567890123456789012"
    • For a proctor room sync doc we do: "Proctor_Room_" + proctorRoomSid
      • ex). "Proctor_Room_PR12345678901234567890123456789012"
  • identity: This is the identity for the sync client, which has to be unique across ALL clients. So, the identity is different based on the user AND what doc they are joining
    • For a student, they can only connect to their own session sync doc, so their identity is just their sessionSid
      • ex). "ES12345678901234567890123456789012"
    • For a proctor, they can join session sync docs and proctor room sync docs, so they have identities for both situations
      • Proctor Connecting to Session Sync Doc: Identity is: sessionSid + proctorAccountUserSid
        • ex). "ES12345678901234567890123456789012PU12345678901234567890123456789012"
      • Proctor Connecting to Proctor Room Sync Doc: Identity is: proctorAccountUserSid
        • ex). "PU12345678901234567890123456789012"
  • token: This is a valid SP token that users are granted from launching in (LTI, Lighthouse, etc)

Optional Fields:

  • initialData: This is a JSON object that you would like to put into the sync doc upon creation
    • ex). { reliableConnection: true }

Getting and Setting values in the Sync Doc

Once you have a SyncClient instantiated, it wraps functionality for the specific document that you passed in. These functions all return Promises, so we have to call them accordingly.

So, if you wish to receive the current data in the sync doc, you would run the following:

twilioSyncClient.getSync()
    .then(data => {
        // do whatever with the data here
    });

If you wish to set data in the Sync Doc, you can run the following:

const objectToPush = {
    firstField: 'Hey There!',
    secondField: 'This is probably good enough for an example'
}
twilioSyncClient.setSync(objectToPush)
    .then(success => {
        // do something if it was or was not succesfully updated
    });

Custom Events

Subscribing

When the sync doc is updated, we will raise events to whoever is subscribed. Below is a list of the events that we raise, as well as a code sample on how to listen for the particular event

  • spSyncDocUpdated: This is an event that will return the sync doc in its entirety every time it is updated.
    • How to subscribe:
      twilioSyncClient.getEventEmitter().on("spSyncDocUpdated", function(data) {
         // Do something with the sync doc data here
      });
  • extensionActionsAdded: This is an event that will return the action object to a subscribed user. If there is a subscribed user, then the action will be deleted from the array, otherwise they will remain in the array.
    • How to subscribe:
      twilioSyncClient.getEventEmitter().on("extensionActionsAdded", function(data) {
         // Do something with the action object here
      });
  • onboardingActionsAdded: This is an event that will return the action object to a subscribed user. If there is a subscribed user, then the action will be deleted from the array, otherwise they will remain in the array.
    • How to subscribe:
      twilioSyncClient.getEventEmitter().on("onboardingActionsAdded", function(data) {
         // Do something with the action object here
      });

Creating

Whenever we update the sync doc, we will create the action for spSyncDocUpdated, so we will not go into detail about that event here. However, we do need to talk about "Actions". Actions are simple JSON objects that are put into one of our "Action Arrays". As of writing this README, we have onboardingActions, which are actions that the onboarding UI needs to execute, and we have extensionActions, which are actions that the extension needs to take.

For example, if I am writing a piece of functionality on the onboarding UI that needs to have the extension inject its password, then I can do that by passing an extensionAction to tell the extension to inject a password. Below is a code sample about how that action would be created.

twilioSyncClient.addAction(ActionTypes.extension.injectPassword);

As you can see, we will use the ActionTypes object that we import to find the available actions. From the ActionTypes object, you can look at extension actions with ActionTypes.extension or onboarding actions with ActionTypes.onboarding. Sometimes actions may take some additional information.

For example, we can tell the extension that we need to end the session, which we can do like this:

twilioSyncClient.addAction(ActionTypes.extension.stopSession);

However, let's say that we also want to redirect the user to a different URL than the default redirect. We can now add some additional information to this action. As a second param, the addAction() function can take an optional JSON object that can be used in some actions. Also, some actions require additional information as the extension will not have all of the information needed to complete all of its actions.

So, if I wanted to tell the extension to end the session and to redirect the user to our end-session screen for automated students. Then I could accomplish that by the following:

twilioSyncClient.addAction(ActionTypes.extension.stopSession, { redirectURL: 'https://app.smarterproctoring.com/#/automated/end-session' });

If you ever want to see what fields are required for an action, look at the ActionTypes file in the client, and any field that is null in the desired action is a field that is MANDATORY to send in.

Sometimes we may need to add more than one action at a time. In this case, it is not the best practice to combine multiple addAction calls, but rather send a batch of actions. To do this, we can use addActions() as detailed in the example below:

twilioSyncClient.addActions([
  {
      actionType: ActionTypes.extension.injectPassword
  }, 
  {
      actionType: ActionTypes.extension.stopSession, 
      additionalInfo: { redirectURL: 'https://app.smarterproctoring.com/#/automated/end-session' }
  }
]);

Here we can see that we take in the same two parameters as the single addAction() call, but they are put as fields inside of an array of objects. Make sure that you put the actions in the order of which you would like them to execute, because actions should be taken as FIFO.

Responding

If you are sending an action that needs a response, we can use the respondTo field. This tells the action taker where to post the resulting data from the action. For instance, when the onboarding UI needs to get the number of displays from the extension, it needs to have the extension run the action of getDisplayCount, but also needs it to respond to the onboarding UI's action array. So, to make this call from the UI, we would do the following:

twilioSyncClient.addAction(ActionTypes.extension.getDisplayCount, { respondTo: 'onboarding' });

As long as the UI is subscribed to the onboardingActionsAdded event, and we see that we provided the respondTo for a response in the call above, then the UI will receive an action that will look something like this.

{
    action: 'getDisplayCount', 
    executor: 'onboarding',
    displayCount: 0
}