Update: Follow up article is published.
If you want to skip the Circuit API introduction and jump right to the example app walk though, then jump down a couple pages to the section titled “IMDb Collaboration”.
Circuit is a team collaboration software supporting chat, voice, video, screen share and much more. It’s available on the browser, as desktop application, iOS and Android. The free version allows up to 100 users and 3 users per conference call without any feature limitation.
Until the new developer portal is available, the information on Circuit APIs is a bit scattered.
The JS SDK and Node.js SDK are almost identical. In fact, the Node.js SDK is a thin layer around the JS SDK. The APIs are identical. The SDK is on GitHub and its README is the best place to start. The SDK is also available on npm and the unpkg CDN.
This SDK is mostly used for one of three types of applications:
- Client-side web applications uses the OAuth 2.0 Implicit Grant where the app acts on behalf of the user. The SDK is used on the client-side (browser). The application walkthrough, later in this article, uses this type of integration.
- Bots use the Node.js SDK or REST API and use the OAuth 2.0 Client Credentials Grant. Bots are a special type of user; they don’t login on behalf of a regular user, hence no OAuth popup asking for user credentials and permissions.
The GitHub page has example applications for each of these types.
To give you an idea, here is a snippet to logon as bot, create a group conversation with two users and send a text message.
The Circuit REST API documentation can be found at https://circuitsandbox.net/rest/v2/swagger/ui/index.html. The REST API does not support audio/video calls.
iOS SDK beta
The iOS SDK is still in beta and can be found at https://github.com/circuit/circuit-ios-sdk.
Android SDK / .NET SDK
Android and .NET SDK are not ready for beta yet. But mobile apps may use the JS SDK with Ionic/Cordova. An Android Ionic app showing video calling is available at https://github.com/circuit/circuit-ionic-starter.
The Circuit SDK supports the following OAuth 2.0 Grant Types. They are described in more detail at https://circuit.github.io/oauth.
Authorization Code Grant: The authorization code grant type is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user’s web browser to open the Circuit OAuth authorization page.
Client Credentials Grant: The client credentials grant type provides an application a way to access its own service account. Examples of when this might be useful include Bot applications that can be added as participant in conversations. This grant type should only be used in a server-side application to keep the secret confidential.
Development of apps should be done on the Circuit sandbox system. Registering an account and an app on the sandbox is simple. Once your app is ready you may request an app on the Circuit public cloud system.
- Step 1: If you don’t already have a sandbox account, register for a free sandbox account. Once registered you can login at https://circuitsandbox.net and invite your friends/co-workers.
- Step 2: Determine what OAuth 2.0 Grant Type you need and register an app using the form on https://circuit.github.io/oauth. The
client_secretfor your app will be emailed to you.
- Step 3: Write an amazing app :)
- Step 4: If you want to deploy the app to the Circuit public cloud system, register for an app here.
Now that we have that out of the way, let’s write our app.
The IMDb collaboration app allows searching for movies or TV shows and provides the capability to collaborate with other users on that movie/show. To keep the scope of the app in check, this first version cuts a few corners such as:
- Rather than searching, only a few fixed TV shows are available to collaborate on
- Collaboration is limited to text messaging (no WebRTC calls)
- Sign in is limited to a few predefined users
I plan to write a follow up article to show a server-side Node.js Bot managing access to the conversations, and other enhancements such as searching the movie database, add WebRTC calling, like/unlike, etc.
The goal of this app is to show how easily the Circuit JS SDK can be added to an existing website. But to show that we first need to create a website. Not to lose too much time creating the site, we are going to use a bootstrap nav template.
I was going back and forth on what JS framework to use. My skills are mostly in AngularJS (Angular 1.x), vue.js, Angular (Angular 2+), Polymer and hyperHTML, in that order. My first choice was to go with Angular to gain some more experience with it, but then thought it would be overkill and make the app too complicated, especially for non-Angular developers. The goal is to focus on the Circuit integration and not the website itself. The other day I was reading about this tiny library called lit-html, written by the Polymer team at Google. I wanted to give lit-html a shot, in hope to to keep the app more web standard based and simple to understand, and most important without having to know a framework to follow the example. If I wasn’t so hungry for a simple, web native framework (well library, not framework in this case), vue.js would have been my choice.
Furthermore I am using lit-html-element to handle some boiler plate code for lit-html elements.
lit-html is only 2 KB and lit-html-extended only an additional 600 bytes. It looks like the next version of Polymer might be incorporating lit-html.
Lit-html is not production ready, but since this is only an example app we’re good :). A good read on that is.
Ok, now let’s finally see some code…
We will create three web components using lit-html:
imdb-app: Main app component. Uses
imdb-header: Render header with navigation links and Circuit user’s display name and avatar.
circuit-chat: Circuit integration showing text messages of the corresponding conversation and allow posting a message. This component also handles the sign in.
Each components derives from
LitElement and is loaded in
index.html as ES6 module. So
index.html will be as simple as:
imdb-app component renders the main app skeleton and the details of the selected TV show.
The list of shows and the selected show are passed to
imdb-header as properties.
Similarly, client_id and conversation ID are passed to
conversation$ is part of lit-html to define an attribute rather than a property. As per web components standard, attributes can be observed via
on-logon event handler is raised by
circuit-chat upon successful login. The
on-<event> syntax is provided by lit-html-extended as shortcut to calling
user setter notifies
imdb-header of the logged in user. This is done by setting the
user property of
imdb-header component defines some properties and renders the html, that’s it. Here is the complete component.
Now we are finally coming to the interesting part, the Circuit SDK integration.
circuit-chat.js file can be viewed on github, but let’s go through the component piece by piece.
connectedCallback is part of the web components standard and called when the element is inserted into a document. Here, a new Circuit SDK client instance is created using the provided
client_id. Then, an event listener for the
item_added event is registered to get notified when a new post is made on this conversation.
updateUserCache gets the name and avatar of the post creator. The post is added to the
posts property which then dynamically updates on the page.
Also, in the
connectedCallback a call to checkLogin is made to see if there is an access token in localStorage, and if so, verifies the token. If valid, the token is used to sign in. The
signinState is updated to render the correct html. By using the
checkLogin API we get around of the OAuth popup showing up for a split second.
Finally in this
connectedCallback an interval is setup to update the relative timestamps (e.g. 5 min ago) shown using the moment library.
invalidate is a function provided by the base class
LitElement to re-render the template if needed.
attributeChangedCallback is also a standard web component function used to observe attribute changes on the element. This is how the
circuit-chat component gets notified when the conversation ID changes. If changed, the posts for the new conversation are fetched and rendered.
The remaining code are four internal functions that make use of the Circuit JS SDK, which are
post. Let’s look at each of them.
signin calls the JS SDK’s
logon API. This will show the OAuth popup for the user to authenticate via Circuit. If successful, a custom
logon event is raised to the parent
getPosts then fetches the post for this conversation and
invalidate causes them to be rendered.
getPosts calls the JS SDK’s
getConversationItems API to fetch the 50 most recent posts.
updateUserCache fetches the user objects of the post creators so that their name and avatar can be shown. The JS SDK
getUsersById is used for this.
post calls the JS SDK’s
addTextItem API to send a new post on this conversation.
And finally the
render function returning the result of a tagged template literal. This is the HTML rendered for this component.
I hope you found this tutorial useful.
If you want to find out more about lit-html make sure you watch the video posted above. lit-html is certainly not suited for every application, but I believe it will have it place in the JS framework/library landscape.
Given that only about 10% of the tutorial is about the JS SDK should be a hint that using the Circuit JS SDK is really simple. There are many code snippets on JSBin and github, and several more complete examples on github.com/circuit.
I plan to write a follow up post which uses a bot (Client Credential Grant) app to dynamically grant users access to collaborate on a TV Show when searching for any show. The bot may also compute and show some analytical data.