How to Efficiently Use Webhooks and Stream Chat

4 min read

Webhooks help us receive all events that occur within our application. Once set up, every event that occurs in our application is sent to a dedicated endpoint via a `HTTP POST` request. Since it gives us information about everything happening in our application in realtime, we can perform various operations immediately after certain events take place. For instance, if a user is offline, we can send them a text message when a message is sent to them in our application.

Chimezie E.
Chimezie E.
Published January 17, 2020

Unlike an API request that's triggered when a request is sent, a webhook gets triggered when certain events occur within the cycle of an application. For example, when a new message is added on Stream Chat, the message.new event sends a payload to the webhook endpoint containing data about the message that was just sent.

In this post, we will demonstrate how to set up and use webhooks in Stream Chat. We’ll improve the chatroom application built in one of my previous tutorials by adding the functionality to send emails to all offline users when a new message is sent in the chatroom.

Remember, in order to use webhooks, we’ll need a URL reachable from public internet. For that, we’ll use Ngrok. If you don’t have Ngrok, click here to learn about how to set it up.

Starting and Exposing Our Application

The first thing we need to do is to start our application. If you haven’t already, clone the chatroom application:

git clone https://github.com/ammezie/laravel-stream-chatroom.git

Then install the dependencies by running the following in your terminal:

cd laravel-stream-chatroom
composer install
npm install

Once that is done, start up the backend of the application by running:

php artisan serve

Then we can watch and compile the JavaScript:

npm run watch

Log in to an existing account or create and login to a new one, and you should see the following screen:

For our webhooks to work, we need to make our local development server publicly available. To do that we’ll use Ngrok.

Go to your terminal and run the following command:

ngrok http 8000

If everything works as expected, you should see the following:

Ngrok provides us with a live public URL that makes our application available over the internet. Copy the forwarding HTTPS URL and save it as we need it in the next step.

Enabling Webhooks on Stream Chat

Our chatroom application is up and running. The first thing we need to do is enable webhooks on our Stream Chat dashboard.

Log on to your dashboard and select the chatroom application (or whatever you named it). Next, click on the Chat tab and scroll down to the Chat Events section and set the webhook toggle to Active. Add the Ngrok URL copied from the last step, followed with /hook and click save.

Testing the Webhook

To test our webhook, we need to send events from our application. We’ll inspect the emitted payload sent to our webhook endpoint via the Ngrok web interface.

Once Ngrok has started, visit https://localhost:4040, and you’ll see the following screen:

Now, when we trigger any event, we will see the payload appear on this page.

Let's send a message in our chatroom to trigger an event:

Now we have verified that our webhook endpoint is receiving the payload, we can add the functionality for our offline users to receive emails when a new message is sent on the chatroom.

Sending Emails to Offline Users

Since Laravel 5.3, we’ve had a simple way to send emails through a mailable class. Let’s create a mailable class to handle it for us.

To test sending emails while in development, we’ll be making use of a service called Mailtrap. You'll need to create a free account if you don’t have one already. Then, copy your credentials from the dashboard:

Once you’ve got the credentials, update your .env with them accordingly:

 // .env

 MAIL_DRIVER=smtp
 MAIL_HOST=smtp.mailtrap.io
 MAIL_PORT=2525
 MAIL_USERNAME=YOUR_SMTP_USERNAME
 MAIL_PASSWORD=YOUR_SMTP_PASSWORD
 MAIL_ENCRYPTION=null

Next, we need to create a mailable class:

php artisan make:mail SendMailable

Running the command will create the file inside app\Mail\SendMailable.php. Open the file and update it with the following code:

// app\Mail\SendMailable.php

 <?php

 namespace App\Mail;

 use Illuminate\Bus\Queueable;
 use Illuminate\Contracts\Queue\ShouldQueue;
 use Illuminate\Mail\Mailable;
 use Illuminate\Queue\SerializesModels;

 class SendMailable extends Mailable
 {
	 use Queueable, SerializesModels;
	 public $name;
	 /**
	 * Create a new message instance.
	 *
	 * @return void
	 */
	 public function __construct($name)
	 {
		 $this->name = $name;
	 }

	 /**
	 * Build the message.
	 *
	 * @return $this
	 */
	 public function build()
	 {
		 return $this->view('emails.hook');
	 }
 }

We have added one property to the class called name that we need to pass when we instantiate the class. We also need to create a view file that will contain the email content.

In resources/view directory, create an emails directory, then a hook.blade.php file inside it. Add the following code:

 <div>
	 <p>Hi {{ $name }},</p>
	 <p>A new message has been sent in your chatroom.</p>
 </div>

This is the content of the email that will be sent once the email is triggered.

Next, let’s create a new controller called HooksController:

php artisan make:controller HooksController

Then paste the following code in it:

 // app/Http/Controllers/HooksController.php

 <?php

 namespace App\Http\Controllers;

 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Mail;
 use App\Mail\SendMailable;

 class HooksController extends Controller
 {
	 public function sendmails(Request $request)
	 {
		 $payload = $request->all();

		 if($payload['type'] == "message.new"){
			 foreach ($payload["members"] as $member) {
				 if($member\["user"\]["online"] == false){
				 $email = $member\["user"\]["id"]."@gmail.com";
				 Mail::to($email)->send(new SendMailable($member\["user"\]["name"]));
				 return 'Email was sent';
				 }
			 }
		 }
	 }
 }

First, we check the type of payload to confirm it’s the event we want to handle (message.new in our case). Then we loop through all the members in the chatroom to find out the users that are offline. Finally, we send the email to them.

Next, we need to create the /hook route we used earlier because that is where Stream Chat will send the payload to.

Add the code below inside web.php:

 // routes/web.php

Route::post('/hook', 'HooksController@sendmails');

There is only one more thing to do before we test this out. Let’s exempt route from Cross-Site Request Forgery (CSRF) production, which Laravel does by default. To do that, add the route to the $except array inside VerifyCsrfToken.php like below:

 // app/Http/Middleware/VerifyCsrfToken.php

 protected $except = [
	 '/hook'
 ];

Now, head to over to chatroom and send a message to trigger the webhook.

If everything works as expected, you should get something similar as below in your Mailtrap inbox:

Conclusion

In this tutorial, we learned how to use webhooks to enhance our chat experience. We’ve also learned how to use Ngrok and Mailtrap to accomplish these tasks. The knowledge you've gained can be used to build more complex chat applications. To find out more about Stream Chat, check out the docs here. You can also check out the webhooks docs for some best practices when working with webhooks.

The complete code for this tutorial is available on GitHub.

Integrating Video With Your App?
We've built a Video and Audio solution just for you. Check out our APIs and SDKs.
Learn more ->