Create a video app with JaaS, React and Vercel
Tags: react
Published: 2021-07-14 19:10:14

## 👋🏼 Introduction
Over the past couple of months, I've had the opportunity to work with the [Jitsi](https://jitsi.org/) team at [8x8](https://www.8x8.com/) on improving the developer experience of their [Jitsi-as-a-Service (JaaS)](https://jaas.8x8.vc) product. One of the most enjoyable parts of my work was building sample apps using the JaaS APIs. I decided to turn one of these apps into a tutorial to share what I've learned and to show off JaaS :)

This tutorial will show you how easy it is to get up and running with [Jitsi-as-a-Service (JaaS)](https://jaas.8x8.vc). This tutorial will build a serverless video meeting application using React, Vercel, and JaaS. Our simple application will provide users with a form to enter their email. That form will request a serverless function to see if the user is allowed to join. If the user can join, the function will generate a [JSON Web Token (JWT)](https://jwt.io/), and the frontend will add the user to the video call.

For the complete code, see this [GitHub repo](https://github.com/chriscorcoran/jaas-hands).

## 📚 Prerequisites
Before we get started, there are a few prerequisites we need to sort out.

* **JaaS Account** - If you don’t already have a JaaS account, you can create one for free by going to [https://jaas.8x8.vc](https://jaas.8x8.vc).
* **Node.js** - If you’re not familiar with node and want to learn more, check out the Introduction to Node.js guide
* **Vercel Account** - You can create a free account by going to [https://vercel.com/#get-started](https://vercel.com/#get-started).
* Any code editor of your choice

## 👷‍♀️ Building a React App
We’re going to start by using the Create React App utility to initialize a new React App. You’ll need to have Node.js installed on your development machine if you don’t already.

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Commands - create-react-app.sh %}

After running `npm start,` you should load the template application by going to [http://localhost:3000](http://localhost:3000).

### Cleaning Up Scaffolding
The Create React App utility creates some scaffolding that we won’t be using. To simplify our project, we can just remove some of that scaffolding now. 

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Commands - cleanup.sh %}

We also need to clean up a few references to these files in `App.js` and `index.js`. In `index.js`, remove the following line: `import './index.css';` In  App.js, be sure to remove the line `import './App.css';`

### Installing Dependencies
For our project, we’re going to need a few different libraries. We will need bootstrap for styling, UUID for generating user IDs, and jsonwebtoken to generate JSON Web Tokens (JWTs). To install these dependencies, simply run this command from inside your project directory.

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Commands - install-deps.sh %}

Once you’ve installed the dependencies, we need to make a small change to `index.js` to load bootstrap. Simply add this line to your existing import statements.

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Snippets - add-bootstrap.js %}

### Creating the UI
Now we’re ready to start building out our UI. We’re going to keep things simple for this application. We’ll present users with a form to enter their email addresses. We’ll use the provided email address to make a request to a serverless function which will determine if the user can join the meeting. If they can, then the serverless function will return a JWT, and we’ll load the JaaS embed.

#### Creating the Layout
The first thing we’ll do is create the layout of our application. It will be a single React component in the `App.js` file. Our layout will have two parts: an email address form and a video call. 

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Creating the UI Step 0 - App.js %}

#### Managing State
In our layout, we have a couple of essential pieces of state that we need to manage. We rely on a variable called ‘allowed’ to control which part of our layout to display. We also need to store the value of the email field to send to our serverless function. 

To do this, we’ll be using React Hooks. We just need to add a couple of lines to our `App` component. You’ll want to insert these lines inside the `App` definition before the return statement.

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Creating the UI Step 1 - App.js %}

## 🏗 Setting Up Vercel
We’ll be using Vercel as our serverless function environment. Vercel makes it easy to develop a serverless function locally and then seamlessly deploy it to the cloud. To get started, we’ll first need to install the Vercel CLI. If you haven’t already. You can install the Vercel CLI by running the following command:

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Commands - install-vercel.sh %}

Once you have the CLI installed, we just need to initialize our project to run with Vercel by running the following command at the root of our project.

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Commands - vercel.sh %}

With our project initialized now, we’re ready to have Vercel run our project locally. First, make sure to close any other instance of the React dev server; once you’ve done that, you can run the following command.

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Commands - start-vercel-dev.sh %}

Just like running `npm start`, the Vercel CLI will start a development server that is available by going to [http://localhost:3000](http://localhost:3000).

## 👩‍💻 Creating a Serverless Function
Creating a serverless function for Vercel to run is easy. First, we need to create a new directory at the root of our project. Vercel relies on convention to discover your serverless functions. So, it’s essential you make this in the root directory of your project and not `./src`.

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Commands - mk-api.sh %}

Vercel will treat any source file you create in `./api` as a serverless function. For our project, we want to create a new file called `join.js`. This will create a new API endpoint at `/api/join`. We’ll use this endpoint to determine if the user can join the meeting and generate the required JWT.

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Commands - touch-join.sh %}

Our serverless function will be relatively straightforward. It just needs to parse the request from the front end, check if the provided email address is allowed to join the meeting, and then generate a JWT. Let’s start with the request handler that will orchestrate this process and generate our response. 

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Creating the API - requestHandler.js %}

As you’ve probably noticed, the request handler is relatively simple and relies on few other functions to check for authorization and generate a JWT. Let’s first start with `isAllowed()`. This function consults a comma delineated list of email addresses to determine if the user can join the meeting. To make it easy to update, we’re storing the list of email addresses in an environment variable.

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Creating the API - isAllowed.js %}

If the user is allowed to join the meeting, we need to generate a JWT that will enable them to enter. For that, we’re using the `generateJWT()` function. This does the bulk of the work in our serverless function. The `generateJWT(0` will create the payload of our JWT, decode our public key, and finally sign the JWT.

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Creating the API - generateJWT.js %}

Inside of `generateJWT()`, we’re calling out to yet another helper function to generate avatars for our users automatically. The `generateAvatar()` function generates a Gravatar URL from the provided email address to populate avatars automatically.

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Creating the API - generateAvatar.js %}

When we put it all together, our `join.js` should look something like this:

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Creating the API - join.js %}

## 🎷 Adding a little JaaS
Now that we have our React frontend and serverless function up and running, we need to integrate with JaaS. To do this, we need to configure our JaaS account, populate our environment variables and then make a few changes to our application.

### Configuring Environment Variables
For our application to work, we’ll need to create a couple of different environment variables. You can do this by creating a `.env` file at the root of your project. Inside the `.env` file create the following variables. You’ll be able to access them from inside your application by using the `process.ENV.{Variable Name}` variables. 

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Add a Little JaaS - config.env %}

You can populate `ALLOW_LIST` with a comma delineated list of email addresses that you want to allow access to the meeting. For example:

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Add a Little Jaas - allow-list.env %}

You can also select `JAAS_ROOM_NAME` that fits your use case. For example:

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Add a Little Jaas - jass-room-name.env %}

For the remaining values, we’ll be consulting the JaaS web console to get the required values.

### Gathering the JaaS Configuration

#### JaaS App ID
Start by heading over to the API Keys section of the JaaS console. The first bit of information we’ll need to make a note of is your AppID. You can store that in the `JAAS_APP_ID` environment variables.

<img src="https://chriscorcoran.github.io/jaas-hands-assets/JaaS%20App%20ID.png" />

#### JaaS API Key
Next, you’ll want to create a new API Key by clicking the 'Add API Key' button.

<img src="https://chriscorcoran.github.io/jaas-hands-assets/JaaS%20Add%20API%20Key.png" />

You will then be presented with a dialogue that asks if you want to generate a new key pair or add your own. For this tutorial, we want to generate a new key pair.

<img src="https://chriscorcoran.github.io/jaas-hands-assets/JaaS%20Generate%20API%20Key%20Pair.png" />

Once the key pair has been generated, you’ll be presented with another dialogue that asks if you want to download the new key pair. For our purposes, we’ll need to download the Private Key.

<img src="https://chriscorcoran.github.io/jaas-hands-assets/JaaS%20Download%20Key%20Pair.png" />

Once you’ve downloaded the public key, we need to base64 encode it to store it in the `JAAS_PRIVATE_KEY` environment variable. To do this, run the following command:

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Commands - base64.sh %}

### Tying It All Together
Now that we have a working frontend and serverless function, it’s time to tie it all together. To that, we’ll need to update our React front end to talk to our serverless function. We’ll do this by updating our App component to catch the `onSubmit` and send a request to our serverless function. 

The first thing we need to do is load the JaaS iFrame API into our React app. To do this, we’ll turn to our good friend React Hooks. We should make sure to group this new hook with our other state management hooks.

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Tying It Together - loadJaas.js %}

Next, we’ll need a function to make a request to our serverless function for the authorization check and JWT generation. To do that, we’ll create a function to catch the submit function on our form that looks like this:

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Tying It Together - onSubmit.js %}

Now we just need to connect this new onSubmit function to our form. To do that, we just add the onSubmit event handler to our layout, like this:

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Tying It Together - formElement.js %}

Finally, we just need to make our call to initialize the video meeting. For that, we’ll add one last function called `initJaas()`. When our request to the serverless function is successful, the front end will call `initJaas()` to start the call.

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Tying It Together - initJaas.js %}

## 🚀 Congratulations!
You did it! You’ve successfully set up a serverless video meeting application using React, Vercel, and JaaS. Now it’s time to ship it! When you’re ready to take it to the next level, run the following command to deploy to the cloud! 

{% gist https://gist.github.com/chriscorcoran/a43f5a995b9c5f3b8d0cf1e7b42fb231 file=Commands - vercel-deploy.sh %}