•April 28th 2020
Group chat can get a bit messy, especially if it’s public and anyone can join. Making a group chat invite-only can help manage the content of the group and the sanity of those in it, in addition to preventing spam users and bots.
In this tutorial, we’ll be building an invite-only chat room where only admin users can invite other users to join a chat room. Upon joining the chat room, users will be able to chat with other users in realtime.
The complete code for this tutorial is available on GitHub.
To complete this tutorial, you'll need the following tech:
Getting Our Stream Chat Keys
To use Stream Chat in our app, we need to grab our Stream Chat API keys. Stream Chat allows you to build a fully-functional chat app in hours, instead of weeks, or even months; we'll use it to build our simple example app in minutes! To get started log in to Stream or create an account. Upon successfully entering your credentials, you'll be delivered to your dashboard, where you can create a new app by clicking the Create App button:
Once that is done, you should see an API KEY and SECRET for your newly created application:
Take note of these keys as we’ll be needing them shortly.
We’ll be using the Laravel installer to create a new Laravel application. Run the following command to create a new Laravel application with authentication scaffolding:
Once that’s done, let’s install the npm dependencies:
Now, we can begin building out our application!
Building the Application
We’ll start by updating the
users table migration in our
create_users_table.php file, within
database/migrations, as shown below:
We updated the
name field to
username and added a new field called
is_admin, which will be used to determine if a user is an admin or not.
Let’s update the fillable fields in our
User.php file, in the
app directory, to have the
username field instead, as well:
Next, we’ll create an
In addition to creating an
Invite model, the command above will create a migration, as well as a controller for the model.
Open up the created migration and update the
up method in the
create_invites_table.php file, within
database/migrations, as shown below:
The fields are pretty straightforward; the
accepted field will be used to determine if an invite has been accepted or not.
Also, let’s mark the fields as fillable in
Invite.php, in the
Before we run the migration, let’s set up our database. For the purpose of this tutorial, we’ll be using SQLite. Update
.env as below:
Because we are making use of SQLite, we can get rid of the other
DB environment variables.
By default, Laravel will look for a
database.sqlite file, so let’s create it:
Now, we can run the migration:
Before we move on to adding functionality to our application, let’s add our Stream keys to our
Be sure to update "YOUR_STREAM_API_KEY" and "YOUR_STREAM_API_SECRET" to the values you grabbed from your Stream Chat dashboard.
Creating Channel and Admin Users
Now, let’s start building the group chat functionality. We’ll start by creating a new channel, which we’ll call "
Chatroom", and an admin user, to administer the group. We’ll be creating a console command to handle these. Run the command below to create a new console command:
This will create a new
InitializeChannel.php file inside
Since we’ll be making use of the Stream Chat PHP SDK, let’s install it:
With that installed, open up
InitializeChannel.php, located at
app/Console/Commands, and replace the contents with the following:
We define the signature of the command and give it a description. Inside the
handle method, we create an admin
user, then we create the
user on Stream as well, assigning the user an
admin role. Then, we create the
channel and make the newly created
user the creator of the
channel. Next, we add the
user as a member of the
channel. Lastly, we return a success message.
Now, we can run the
Since we want users to join our group chat only by invitation, let’s remove the ability to register, which was added by Laravel authentication scaffolding. We can do that by updating
web.php, in the
routes directory, with the below:
With the channel and admin users created, let’s add the functionality to invite users to our group chat. We’ll start by creating the routes. Add the code below inside
Since we already have
InviteController.php, let’s open it up and add the following code in it:
Next, let’s create the view file. Inside the
resources/views directory, create a new
invites directory and create a
create.blade.php file inside it, then paste the following code in it:
The form has just one field, which is for capturing the email address to send an invitation to. Above the form, we have in place to display flash messages, if there are any:
Let’s move on to adding the implementation for processing the form. Add the following code to the top of
First, we get an
invite matching the submitted email address. If an
invite already exists for the email address, we flash an appropriate message depending on whether the
invite as been accepted or not. If no
invite was found, we create one for the email address, then send an email with the invitation link.
For this tutorial, we won’t be setting up a mail driver. Instead, we’ll log the mail to a file. Let’s set the
MAIL_MAILER to "
.env as shown below:
Now, if we try sending an invite, it should be logged inside
storage/logs/laravel.log and look something like the below:
I’m using Laravel Valet, hence my URL:
Let’s add a link to access the invite users page. We’ll add it in the navbar (
app.blade.php) immediately after the
While we are here, let’s update the navbar to show the user’s username instead of the name:
With these changes, your navbar should look like the below:
Joining Group Chat through Invitation Link
Once a user is sent an invitation, the user can click on the link in the email to join the group chat. To make this possible, add the following code inside
Next, add the following code inside
First, we retrieve the
invite matching the
token, if it exists. If the invitation has been accepted, we simply redirect the user to the
home route. Otherwise, we render the "register"
view and pass along the
register view is already in place; we just need to update it slightly. Replace the
resources/views/auth/register.blade.php as below:
We made the
We’ll still make use of the default Laravel
app/Http/Controllers/Auth/, to handle registration. Open it up and update
create methods to make use of
username instead of
name like below:
RegisterController.php, add the following code to the very top:
Once a user registers successfully, the
registered method is called. Inside this method is the perfect place to mark the
accepted, create the
user on Stream, and, finally, add the
user to the "Chatroom"
Generating an Authentication Token
Let’s add the functionality for generating an authentication token, which Stream Chat will use to authenticate a user.
First, let’s create the endpoint inside
Next, create a
and add the following to it:
This generates a token using the user’s
username as the ID.
Adding Chat Functionality
With the backend functionality in place, let’s move on to adding the chat functionality. We are going to rename
ExampleComponent.vue, inside the
resource/js directory, to "
ChatRoom.vue" and update its reference inside
resources/js/app.js as below:
Now, replace the content of the
ChatRoom component with the following:
template is made up of two parts: the
members list and the chat itself. We generate a
token for the authenticated user, then we use the
token to instantiate the Stream Chat client. We also initialize the
channel and watch for activities on the
channel, which allows us to know when a new
message is sent on the
channel as well when new
users join the
channel. Lastly, we have the functionality for sending a new
For a guide that covers these in detail, check out my previous tutorial.
Next, let’s make use of the
ChatRoom component. Update
home.blade.php as shown below:
ChatRoom component accepts the authenticated
user as props, which we are passing in.
Securing Our Application
Remember we said only an admin user can invite users to join our chatroom? But, as it stands, anybody can do this, even if they're not logged in. Let’s change that! Laravel provides an
Authenticate middleware, by default, which we can use to enforce access to only authenticated users. We’ll create another middleware for enforcing an authenticated user is an admin.
Run the command below to create an
and update the
handle method as shown below:
Here, we are simply redirecting the authenticated
user to the
home route if the
user is not an admin. If they are an admin, we allow the
user to access the requested page.
Before we can make use of the middleware, we need to register it. We’ll register it as a route middleware by adding it inside the
$routeMiddleware array, in
app/Http/Kernel.php, like so:
Now, we can make use of the middleware inside
web.php using the
Now, not only does a user have to be authenticated to access these routes, but they must also be an admin!
In this tutorial, we have seen how to build an invite-only group chat using Laravel, Vue.js, and Stream Chat. We created multiple pages and authentication layers to our simple chat, but there is so much more you can do! To learn more about Stream Chat and its exciting features, check out the docs!
Thanks for reading, and happy coding!