The COVID-19 pandemic has not only affected the physical gathering of Software Engineers, for events such as local meet-ups and global annual conferences, moreso , other live events where the gathering of one or more persons is inevitable. To prevent exposure to the virus, participants of the supposed live events will rather prefer to have it hosted online and join at the comfort of their homes.
A couple of options such as YouTube and zoom come to mind for such events. But imagine if you needed to build an application with functionalities and features robust enough to hold a live event, that’s going to be a lot of work.
In this tutorial, I will show you a simpler way to build a Virtual event site as an extra functionality for your existing application or as a stand-alone system. For this, we will use Laravel to build the appropriate backend logic and then use Vue.js to handle all the interface and frontend logic. The core and the most interesting section of this application is the chat feature, which will allow participants of an event to chat with each other. To achieve this we will leverage CometChat infrastructure.
While I will do my best to explain any complex concepts and terms in this tutorial, the following prerequisites will help you get the best out of this post.
Basic knowledge of building RESTful APIs using Laravel
The application that will be built in this tutorial is a live event platform that will allow users to view multiple events and be able to select, join and participate in a chat during the live session as shown here:
Users of this application will be able to:
Register and Log in
Create an event
View the list of events
View a single event and
Be able to participate in a chat
Bear in mind that in an ideal production environment, it is advisable to allow a particular user with the required privilege, such as an admin, to create and moderate the live events. But to reduce complexity in this post, we will allow all registered users to have the access to creating events.
This application will allow users to register by providing their details such as name, email and an optional avatar_url. Once the user is created successfully, we will utilize CometChat RESTful API to create such a user on CometChat. To uniquely identify and easily authenticate each user later on CometChat, an authentication token will be generated and saved against the user’s details in the database.
Also, for the log in process, a user with the appropriate credential will provide his or her details, and once successfully authenticated, such user will also be logged in on CometChat by making an API call using the REST API.
Lastly, one of the most important feature of this application is the live event. We will set up different endpoints to manage events in a bit. Every event will be regarded as a group on CometChat, so once created within our application, we will send an API request to CometChat to easily create the corresponding group with a particular guid as well. Only authenticated users who belong to a particular group (event) will be able to join and participate in any chat.
Creating the backend API
In this section we will begin by using Composer to install Laravel. Issue the following command from the terminal:
The preceding command will create a fresh Laravel installation in a directory named lara-virtual-event and place it in your development folder or where you ran the command from. Then, navigate to the new project and run it using the following commands:
View the welcome page of Laravel on http://localhost:8000.
Create and modify migration files
First we will modify the existing User model and its corresponding migration file that came installed with Laravel by default and after that, we will create a migration file for Events.
Start by opening the User table migration file and replace its content with the following:
In addition to the default fields, we modified the file to create fields for token and avatar_url in the database.
Update the protected fillable
Open the User model file in app/Models/User.php and modify the $fillable property to reflect this:
Create migration file for event
To create and manage events, we will need to create an Eloquent model, a database migration file and a controller. Run the command below to do all these:
php artisan make:model Event -mc
With the preceding command, we took advantage of the flexibility offered by Laravel artisan command to automatically generate a Model, migration file and controller using a single command. The mc option represent, a migration and controller. With that in place, lets edit the default contents for the migration file and model. Start by opening migration file in the database/migrations folder and replace its content with the following:
Next, update the $fillable property by using the following content for the event Model located in app/Models/Event.php file:
With all the appropriate models and migration file created, proceed to create a database for your application and also update the .env file with its details:
Swap the YOUR_DB_NAME, YOUR_DB_USERNAME and YOUR_DB_PASSWORD with the appropriate credentials.
Now, issue the following command to run the migration file and create the appropriate fields in the database:
php artisan migrate
After running the previous command to set up the database tables, we will proceed to set up and implement the authentication logic and other backend business logics for the application.
Setting up Laravel authentication
To begin the Authentication aspect of this application, we will utilize the Laravel/UI scaffolding package. Run the following command to install it using Composer:
composer require laravel/ui
This package provides the Bootstrap and Vue scaffolding for a new Laravel project. Once the package has been installed, we will use the ui Artisan command to install the complete frontend scaffolding. Issue the following command to achieve that:
php artisan ui vue --auth
This will install Vue.js and also create authentication controllers as well as its corresponding views. After the installation is done, you will run the command below to install all the dependencies created in the package.json file for the UI scaffold:
Next, run these commands to install additional dependencies:
In this section, we will start working on the business logic for the backend API by modifying the authentication logic within Laravel to fit in into our case and also create the appropriate logic to manage events.
Start with the RegisterController found in app/Http/Controllers/Auth folder and replace its content with:
In the file above, we specified the required fields that should be validated during the registration process. And once the user was registered successfully, we made an API call to CometChat’s REST API to create credentials for the user on CometChat as defined in the createUserOnCometChat() method above. Lastly, we generated an authToken to uniquely identify a user on CometChat and save the token against the details in the database.
Next, open the LoginController.php file located in the app/Http/Controllers/Auth folder and use the following code for it:
Once a user has been authenticated successfully, we returned a JSON response with the user’s details.
Creating backend logic for managing events
In this section, we will update the EventController.php file with the appropriate code to create and view events. Bear in mind that we want Laravel to return the required views to render the form for creating events but use Vue.js components to handle its logic instead of blade template engine. Open app/Http/EventController.php file and replace its content with the following code:
First, we created an index() method to render a view that will display the list of events as retrieved from the database. Immediately after that, we created the following methods:
createEvent(): This method used the Laravel request method to retrieve the input from the file submitted to create a new event. Once retrieved, we used the create method, which accepts an array of attributes and inserts it into the database.
viewEvent(): This methods takes in a particular id as parameter, uses it to fetch such event from the database and returns it as a JSON response.
viewEvents(): This method was used to retrieve the entire list of events from the database.
Update the routes
With the logics out of the way, navigate to routes/web.php file and update its content with the following:
We included the endpoints to reference all the methods created within all our Controllers. These endpoints will be called from within the frontend of the application.
Setting up the frontend
Here we will focus on the frontend logic of the application. This will include creating the appropriate Vue components to consume the backend resources created with Laravel earlier. Also, it is important to note that Vue components will also be used within the blade file created for rendering views. This way, Laravel will still be responsible for routing but instead of handling all the logic with the blade template engine, Vuejs components will be used.
npm install @cometchat-pro/chat --save
Once the installation is complete, navigate back into the Laravel application and add the following variables to the .env file:
Replace the placeholders with the appropriate details obtained from your CometChat dashboard. Please be sure to use the value of your REST API Key instead of the Auth Key
Initialize CometChat app
Initializing CometChat within an application is part of the core concepts specified for communicating with the CometChat APIs. To do that within our application, open the resources/js/app.js file and use the following code for it:
Just before we start creating the necessary Vue.js components for this application, we need to set up few configurations:
Install a plugin that will help transform static class properties. The class properties are declared within the CometChat UI kit that we will download later in this tutorial. With this in place, we can avoid any unnecessary errors.
To begin, run the following command from the terminal to install @babel/plugin-proposal-class-properties:
Once the installation is done, create a new file named .babelrc within the root of your application and use the following content for it:
Next, navigate to webpack.mix.js file and update its content as shown here:
Here, we specified the any file with an extension of .wav be handled by Webpack using file-loader.
Creating views and cloning the UI Kit for Vue
In this section, we will create register, login and a event view for users. To begin, create a folder named views within resources/js folder and create the following files within the newly created folder:
Lastly, we will use the UI Kit created by CometChat team to set up group chat view. This comes with the benefit of an appealing user interface and a proper structure for chat applications. To use the kit, clone or download it from this repository using the following command:
Once you are done, open it with a code editor or any file explorer and copy the cometchat-pro-vue-ui-kit folder and paste it in resources/js folder. Now copy all the dependencies from package.json of cometchat-pro-vue-ui-kit into your project's package.json and run npm install to install them.
Now, we are set to start creating Vuejs components for all the views in this application. Start by opening the Register.vue file and use the following content to replace its <template></template> section:
Here, we built the HTML form with input fields for user’s name, email, password and avatar_url. Next, paste the following code after the <template></template> section:
As mentioned, the authentication flow for this application is to register users within it and also create such user immediately on CometChat using the Create User REST API. Here, we created the registerAppUser() to register users within our application.
Open the Login.vue file and use the following code for its <template></template> section:
We created the input fields for email and password. Next paste the following <script></script> that contains the logic to login a user:
Once a user can log in successfully into our application, we will retrieve the token generated earlier and use it to authenticate such user on CometChat.
To create an event, a user must provide the event title, description and YouTube live stream URL. Populate the createEvent.vue file with the following code to receive those inputs:
Next, add the following to the <script></script> section.
From the file above, we defined a method named createEvent() to create an event as a group on CometChat. Once successful, we also created the details of such event in our database.
List of events
Navigate to Events.vue file and paste the following code to display the list of created events:
The content above will render a list of live events and also display the thumbnail for each event. Next, paste the following code in the <script></script> section of the file:
Once the component was ready, we sent a GET HTTP request to our API to retrieve the list of events from the database. We then proceeded to create two other methods:
getVideoThumbnail(): This method takes the Youtube url as parameter and then returned a thumbnail version of it.
redirectAndViewEvent(): This method checks if the currently authenticated user on CometChat has joined the group or not. If the user is yet to be part of the group, we used the CometChat.joinGroup() to add the user and redirect them accordingly.
Lastly, for styling purpose, add the following styles to the <style></style> section of the Events.vue file:
View a single event
The single event component will render a video container and a group chat view. To set this up, use the following code for the <template></template> section of Event.vue file:
Aside from the video container section, we introduced and used a comet-chat-messages components to render messages for the particular group (event) selected from the event listing. This component was imported from the CometChat UI kit for Vuejs and it takes the type and the group object as props. The props are very important as this component will throw an error without them.
Once this component is mounted, we called the CometChat.getGroup() to retrieve the group object and assigned it to the groupEvent variable reference within the view.
To make this page layout more appealing and properly structure, use the following style for the <style></style> section of the file:
Import all the created components
So far, we have built the user interface into smaller Vue.js components and before we can make use of them within the appropriate Blade templates, register them as Vue.js components, by adding them to resources/js/app.js as shown here:
Modifying Laravel blade template
Here, we will make use of all the components created so far within each blade file from Laravel.
Login blade file
Start with the login.blade.php file in resources/views/auth folder and replace its content with the following:
Register blade file
For resources/views/auth/register.blade, use the following content:
Home blade file
The list of events will be rendered within the resources/views/home.blade.php file. So open it and replace its content with the following:
Change the content rendered on the homepage by replacing the contents of resources/views/welcome.blade.php file with the following:
Open resources/sass/app.scss and update its content with:
This is the CDN file for font awesome icons.
Create event directory
Create a new folder named events within resources/views folder and then create two new files named create-event.blade.php and event.blade.php inside the newly created folder.
Next, open event.blade.php and use the following content for it:
And for the create-event.blade.php file, update its content with the following:
To update the Layout file. Replace the content of resources/views/layouts/app.blade.php file with the following:
Test the application
Now that we have included the appropriate logic for the the frontend of our application, we can now serve the application by issuing the commands below. This first command will run the Laravel application:
php artisan serve
While the command below will compile all the assets including Vue:
npm run watch
If you come across this error
This is because we have two images compiled by webpack with the same name and casing from different locations within the project. One of the best temporary fixes is to rename one of the files and also update its reference.
Navigate to resources/js/cometchat-pro-vue-ui-kit/src/components/Messages/CometChatMessageActions/resources folder and rename edit.png to editIcon.png. Also rename add-reaction.svg to add-reaction-icon.svg. Next, open resources/js/cometchat-pro-vue-ui-kit/src/components/Messages/CometChatMessageActions/CometChatMessageActions.vue file and update the import of the files renamed above as shown below:
import reactIcon from "./resources/add-reaction-icon.svg";
import editIcon from "./resources/editIcon.png";
Next, ensure that the application is opened from two different terminals and then proceed to run the following commands again:
php artisan serve
npm run watch
From the second terminal.
Navigate to http://localhost:8000 from your browser. Next, go ahead and Register:
Or Log in if you have created an account. You can create a new event or view the list of available events and select one to joined the stream as shown here:
In this post, we built a virtual live event system where authenticated users can create multiple events, add a YouTube live stream link, and most importantly chat with one another. The chat functionality was implemented easily by taking advantage of the existing robust APIs and components created by CometChat. This saved us a lot of time.
The complete source code for the project built in this tutorial can be found here on GitHub.
About the author
Oluyemi is a tech enthusiast with a background in Telecommunication Engineering. He ventured into programming with a keen interest in solving day-to-day problems encountered by users. He has since directed his problem-solving skills towards building software for both the web and mobile platforms. As a full-stack software engineer with a passion for sharing knowledge, Oluyemi has published many technical articles and content on several blogs worldwide. As s tech-savvy person, his hobbies include trying out new programming languages and frameworks.