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.