2. LiveChat APIs in practice
Welcome back to The Practical Guide to Building LiveChat Apps. In the second episode, you’ll implement authorization and functional methods to our application using the Accounts SDK and LiveChat Configuration API.
Let’s get coding!
Hello! This is Oliwia from the LiveChat Developer Program, and welcome back to the Practical Guide to Building LiveChat Apps! In today’s video, we’re moving straight to the practical part of the course. That’s right — today, we are coding!
We prepared a training app for you, which after the previous video, you should already have fetched on your machine. If you haven’t done that yet, now’s the time to do it.
Naturally, you’ll find the link to the LiveChat Tag Master training repository in our resources file.
So, as a result of today’s video, you’ll know how to implement a working authorization using the redirect authorization method, and also, how to add functional API methods to your apps. Our application’s name is Tag Master, which means that our app will allow for extended tag management. However, as an extra, the final application file will also allow for configuring canned responses.
To give you a broader view of what’s already inside our app, in the repository, you’ll see that the app has already been divided into three separate branches we’ll be opening in a certain order. Each of these branches includes a specific part of code indicated by its’ name.
So some of the coding that’s not essential to the topic of this video — like implementing the app’s frontend design or certain UI components — has been done off-screen.
Now, let’s open the repository and check the first branch called `base`. In here, we have two files - one is the `package.json`, and the second one is a very simple `index.js` file. Let’s dive into these and see what they do.
So the `package.json` file imports the necessary libraries we use in our project. There, you’ll find the Accounts SDK library responsible for authorization with the LiveChat API, and the LiveChat Design System, which we’ll use components from. We also use Axios, a library for communication with APIs, the Material UI library, which imports different icons, and the styled-comoponents library, which is a library for application styling. Naturally, since this is a React application, we also added relevant React dependencies.
We also modified the command `start` by adding an HTTPS flag to it so we can obtain a secure encrypted HTTPS connection instead of just an HTTP one.
So to begin, we need to install the required packages and dependencies using the `npm install` command in the repository file directory in your terminal. And to open the app, simply type `npm start`. And, as soon as we do that, we can check in our browser if our app runs fine.
So, we see that’s working! Now, we can move on to set up our application in the Developer Console.
So after creating a new app on our account, we’ll have to do some simple configuration that will allow us to code the authorization mechanism in our app, and as a result of that, communicate with the LiveChat API.
For that, we’ll need to add building blocks. And the first building block that we’ll have add to our app is the Agent App Widgets. That’s a block for displaying custom embedded widgets in the LiveChat Agent App. Currently, we’re using a local environment to run our app, so we’ll put the localhost address into the widget source URL. We’ll also use the default Chat Details placement for the app.
The last thing we have to do is to add relevant scopes for the API methods we want to use in our application. Since our app allows for tag and canned responses management, we’ll select scopes responsible for creating, reading, and modifying tags. And the same for canned responses.
After we save the changes, we can install the app privately to check whether our local environment displays properly in the Agent App. Later, this will also allow for eventual further testing and debugging.
And if you want to know more details about building an app in Developer Console from start to finish, we recommend checking our recent video on this subject. You’ll find this video on the LiveChat Insider YouTube channel.
Alright! And once we move on to the Agent App to check our sample app, we can see that it looks great — exactly the same as on the localhost. To differentiate our app from other apps we’ve installed on our test license, we uploaded a custom icon for it off-screen. So, now we can move on to our code editor and continue with coding.
We’ll be starting our work on the base branch, and the final code of the authorization part will be available for you on the branch named authorization.
So in this branch, off-screen, we added a simple spinner component to indicate a loading state, as well as a global styling to remove unwanted scrollbar in the app’s iframe. And the styling has already been implemented in the app’s main file. Naturally, both of these files are available on the authorization branch. We also started our app using the `npm start` command in the terminal.
So once we do that, we want to export the config object so we can use it in other files. When we have that, we can go to the main file. This is where we’ll create a hook for authorization with the LiveChat Accounts instance.
So, we’ll create an arrow function hook that will accept two parameters — our app’s `client_id` and `accounts_url`. We want to define a state for this hook, so we’ll need to add the useState React hook in our imports as well. And the default value of our hook will be a `null`.
Now, we’ll also import the LiveChat Accounts SDK to our file so that we can create an instance for the Accounts SDK. The Accounts SDK instance will accept `client_id` and `server_url` as parameters.
For authorization, we need to define a useEffect hook. So we’ll also need to add the useEffect to our React imports. As a parameter, this hook will accept a function and an array. In our useEffect hook, we want to define an async authorization function, and we’ll use the try-catch construction for it.
So for our authorization, we’ll be using the redirect authorization method. To give you a background of how this works, this method redirects our app to the LiveChat Accounts server, where we authorize, then, we go back to the app with the authorization data found in the URL.
And if you want to read more about this authorization method, be sure to have a look at our explainer article, where we dive deeper into authorization methods available in the Accounts SDK.
So as mentioned, the first thing we want to do is to check if the authorization data is present in the URL. We’ll use the async Accounts SDK method for this, which returns some authorization data for us. And since this is an async method, we’ll have to use the await construction. After that, we’ll use our predefined AccountsSDK instance, on behalf of which we’ll use the redirect authorization method, on which we’ll use the authorizeData method.
To verify the validity of our token, we’ll use the Accounts SDK `verify` method. So the verify function accepts the authorize data from our URL as its parameter. We do this as, for example, our token might be already expired, or else; have the wrong scopes assigned to it — there are a couple of things that could go wrong here, so it’s the best practice to check the token’s validity.
And, if the authorization data is correct and valid, we can save this to the state of our hook. Here we’ll save the access token from the authorizeData, and set this in the hook’s state.
And since this function can result in errors, we’re using the try-catch construction. If the authorization doesn’t go right, we’ll have to handle an error. For that, we’ll redirect the user to the authorization server again with our `authorize` function.
And currently, the authorization function isn’t called anywhere outside of here. So we’ll need to find a place to call this function. Ultimately, we want to return the accessToken from the useEffect hook, and use this hook in our application. Our function accepts config as its parameter, so we’ll have to import the config to this file as well. And then, input this config as a parameter.
We’ll also have to handle a situation where we don’t have an access token yet. So, if the token’s not available yet, we’ll return the imported spinner component we created off-screen as the loading state. So, if there’s no access token, we show a loading spinner.
Now we can check if our authorization works, so let’s move to our app. As you can expect, currently, we’re authorized, so we don’t see any specific error or anything out of the ordinary happening in our browser. But to be 100% sure everything works right, we can console log our access token and check in the browser’s console whether this works as we expected. And, as you can see, everything works correctly!
So, now we can go to the real deal and implement code communication with the LiveChat API. For that, we’ll open the apiCalls branch. In this branch, off-screen, we also implemented some code modifications. Those would be a user interface and components that we’ll be using in our further code work.
So the first change is that we extracted the body of our main app to a separate file in the components folder. In this file, we utilized tabs from the LiveChat Design System to separate tags and canned responses that our app will allow to modify. Since in this video we’ll be working just with the tags, we assigned the tags tab to a relevant, separate component. And in the Tags component, we’ll find the tags list that’s visible in the app. So far, what we have here is just one static tag, but in a moment, we’ll show you how to fetch the tags from our LiveChat license using an appropriate API method.
In the Tags component, we also implemented two modals — for adding and removing tags. Both modals are coded to be fired on a button click.
To start working with the LiveChat API, we’ll need to update our configuration file. So we’ll add a base URL of the LiveChat API. To do that, we need to add a `livechatAPI` key with the LiveChat API URL as the value.
Our next step would be to create an instance for the API, which we’ll use to send requests. For that, we’ll create an `api.js` file, in which we’ll import the Axios library. As a reminder, it is the Axios library that allows for communication between external APIs. Also, we’ll import the config to this file.
So the first thing we want to do here is to make a function for creating HTTP requests. This will be an arrow function, that accepts an HTTP method as its first parameter - for example, GET, POST, and so on. Secondly, it will accept a parameter to specify a route to the API we want to use. As a third parameter, we’ll pass the access token for our authorization. And ultimately, as another parameter, we might want to pass the payload — so the body of our request. And we’ll call this parameter as data.
So from this function, we want to return the Axios instance. The first element that our Axios configuration will accept is the method that we pass in the function as its argument. Then, we need to specify the URL; and the URL will consist of two elements. The first element is the base URL that we can read from our config file, and that’s the `livechatAPI` address with a specified route to the method we want to use. Next, we want to specify the headers for this request with key-value pairs as the value.
The first pair would be the authorization, which in the case of LiveChat is a Bearer token, followed by the access token. The LiveChat API also requires the `Content-Type` header, so we need to specify this as well. Additionally, we’ll pass the `accept` key with the same `application/json` value as the content-type. And there’s that for the headers. As the last parameter we pass to our HTTP request is our data payload, so the possible body of our request.
Now, we also need to consider that sometimes requests return errors, and we need to handle them as well. So we’ll create an arrow function with error catch construction that will print the error in the browser's console.
And that’s how our whole function for the HTTP requests would look like. Now we need to create an API instance that would include the requests we want to send. So, we’ll create an API object which will accept different functions.
The first function we want to create is a function to fetch tags from the LiveChat Configuration API. So we’ll create a function called fetchTags that will accept our authorization access token as one of the parameters, and will call the createApiRequest method we created just before. As a first element, we’ll need to pass the name of the method. To keep the React-like approach, we’ll define a POST const for this. Then, we can send this const as the first parameter in our function. The next parameter will be the route to our API directory. The next thing is to pass the access token, and in the case of this exact method we’re using for fetching tags, the payload will be an empty object. And, the last thing we need to do is to export this API instance.
Now, we want to go to the Tags component. Here, we’ll call the method we just created. And the first thing we want to do is to import our `api.js` file from the utils folder.
Next, we want to define the method that will fetch the tags from our LiveChat license. The access token is one of the props of this component, and after fetching the tags, we want to save those in the state of our component too.
To use this method, we need to use the useEffect function. As a first parameter, this function will accept another arrow function, which we’ll call updateTags. As a second parameter, it will accept the dependency array, which in our case, is empty.
Previously, as an initial parameter for the tags view, we mentioned that we display some mockup data. We don’t need this anymore, as we implemented a dedicated function to fetch them directly from the Configuration API. So now, we can initialize our tags with an empty `null`.
And, now’s the high time to check in the Agent App if all we did even works! And, as we can see, there are definitely some tags fetched from the API, so it means it works well. Also, the exact same data is visible on the localhost. But to be 100% sure, we can check in our browser’s network if the tags are fetched correctly.
So since this works fine, we can move on to creating other requests our app will utilize. So we’ll create another HTTP request — now to create tags. This function will accept two parameters - a tag and an access token. We’ll also use the createApiRequest that we defined prior. Same as before, we’ll use our method, a POST const, a route to the API directory, the access token, and the payload object, which will accept the `name` key and tag name we want to pass as its value.
So now we’ll use this new method in our main Tags component file. For that, we’ll have to import the API object here as well. We’ll implement this method on the onSubmit function, which will call the HTTP request to the LiveChat Configuration API. So the first thing we want to do is to apply the event prevent default, and then, create a loading state for this component. Next, we’ll call the createTag API method we created. As a tag, it accepts the state of our tag component, and the access token has already been passed as a props.
So after we add a new tag, we’ll want to update the state of our app with the newly fetched tags. This way, we can make sure that the state of our app will be the same as the backend data. And for that, we’ll need to call the updateTags function.
So what we have to do now is to call the update function inside of our component — here. As props, we want to pass the updateTags function we created. So after sending a request to create a new tag, we want to call the update function. Ultimately, we want to reset the state of our app. For that, we’ll use an arrow function, that will both close the modal for adding tags, stop the loading state, and reset the tags we’ve been creating before.
Alright, so let’s test that and try to create some new sample tag. It looks like everything’s working correctly as well!
So, the last HTTP request we’ll create in our API file today is a request to remove tags. And we’ll call this request removeTag. Similarly to the createTag function, the removeTag will accept the tag we want to remove as a parameter and the access token. So as you can see, this function has pretty much the same pattern as the createTag function. For this one, we also need to use the createApiRequest method. Then, we’ll need to define the method, which is again a POST const, the route to the API, the access token, and lastly, the name of the tag we want to delete in the request’s payload.
To put this method to use, in our Tags component, we’ll define a tag removal mechanism on the onDelete event. So the first thing we’ll do is to set the state of our application, which will accept the previous values, and the tag to remove as its parameters. Thanks to that, we’ll know which tags we want to remove — as we might want to remove more than one tag at a time.
Next, we’ll start the loading state and utilize our imported API to remove the tag. Here, we’ll pass the tag we want to remove, as well as the access token. After removing a tag, we want to call the update function again to make sure the tags are up to date. And ultimately, we also want to reset the state of our component with an arrow function. Inside of this function, we’ll set the tag to remove as a `null` and stop the loading state, just as we did previously with the createTag function.
So let’s check if this works in our application on the localhost and try to remove a tag. It appears that it works just fine! Now we can test how it works in the Agent App as well. We’ll try to add a new tag. Good, works well! Now we’ll see if our app removes the tag without any errors. Seems to be all good, great!
Oof, that was something! Now, we have a fully working and running application. If you want to update your code to the most recent state with canned responses methods implemented as well, you can simply switch to the master branch where it’s all available for you to check.
In the next video, we’ll teach you how to deploy this application to an external hosting. We’ll explain how to use three different solutions - Firebase, Netlify, and Heroku. You’ll also receive a great insight into what hosting you should choose for your app, depending on what you’re particularly interested in building.
So, thanks for sticking with us, and see you in the next one!
3. Deploy your app
You’ll learn how to deploy your app for production using an external service: Heroku, Netlify, and Firebase.
[Build] fast. Sell far.
Join thousands of top performing developers
and build your passive income.