Laravel 5.3 ships with a notifications feature that allows you send short updates through various services like Slack, SMS (Nexmo), Email, etc., and boy, is it wonderful.

From the Laravel docs:

…notifications should be short, informational messages that notify users of something that occurred in your application. For example, if you are writing a billing application, you might send an “Invoice Paid” notification to your users via the email and SMS channels.

We mostly use Slack on the teams I work with, and I know how helpful it is getting quick updates when stuff happens.

New User Notification for Selar.co


Creating a notification

If you’re using Laravel 5.3, you can create a notification using Artisan:

php artisan make:notification TaskCompleted

If you are on Laravel 5.1 or 5.2, and for some reason don’t want to upgrade, you will have to pull in the laravel-notification-channels/backport package, and load the service provider before running the above command. Check the package repo here.

Running the make:notification command will create a notification class at app/Notifications/, which looks like this:

# app/Notifications/TodoCompleted.php

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;

class TodoCompleted extends Notification
{
    use Queueable;

     /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

     /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

     /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        return (new MailMessage)
                    ->line('The introduction to the notification.')
                    ->action('Notification Action', 'https://laravel.com')
                    ->line('Thank you for using our application!');
    }

     /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}

The via method is used to determine what notification channel to use. Laravel notifies users (or notifiable entities) via the array of channels returned by this method. The channels available out of the box are slack, nexmo, broadcast, mail and database.

The via method receives a notifiable instance which is an instance of the class to which the notification is being sent. You can use this to customise the channel for each entity you’re notifying, for example, by doing something like this:

public function via($notifiable)
{
    return $notifiable->prefers_sms ? ['nexmo'] : ['mail'];
}

To send messages via a channel, a to{Channel} method needs to be defined in the notification class, an example is created by Laravel in the above file with the toMail method, for handling Mail notifications. The toArraymethod is a fallback that handles all channels not specifically customised.

Setting up for Slack

Note: Before you can send notifications via Slack, you must install the Guzzle HTTP library via Composer: composer require guzzlehttp/guzzle

Adjusting the ‘hypothetical’ TodoCompleted.php file for our Slack Notifications, we would have something like this:

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\SlackMessage;

class TodoCompleted extends Notification
{
    use Queueable;

    private $task;

     /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct($task)
    {
        $this->task = $task;
    }

     /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['slack'];
    }

     /**
     * Get the Slack representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\SlackMessage
     */
    public function toSlack($notifiable)
    {
        $task = $this->task;

        return (new SlackMessage)
            ->success()
            ->content("A task has been completed")
            ->attachment(function ($attachment) use ($task) {
                $attachment->title($task->title, route('task', $task->id))
                    ->content($task->description);
            });
    }

     /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            'title' => $this->task->title,
            'description' => $this->task->description
        ];
    }
}

You can check for other formatting options for Slack in the Laravel Docs here.

Setting up our Notifiable

A Notifiable is an entity that can be ‘notified’. These are typically users, but technically any Eloquent Model can be a notifiable by importing the Illuminate\Notifications\Notifiable trait.

Certain notification channels expect certain information available on the notifiable. For example, the slack channel requires the webhook URL for your Slack team, so it knows what team to route the notification to. You can specify it on the model like so:

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Model;

class Admin extends Model
{

    // Import Notifiable Trait
    use Notifiable;

    // Specify Slack Webhook URL to route notifications to 
    public function routeNotificationForSlack() {
        return $this->slack_webhook_url;
    }
}

To get your Slack Team webhook URL, go to your team’s Slack account, “Apps and Integrations” section (https://{yourteam}.slack.com/apps). Choose the “Incoming Webhook” type and add a new configuration. Then copy the webhook URL and make use of in your Laravel App.

Tip: You can save the webhook url in your .env and use in your model using the global env() function:

public function routeNotificationForSlack() {
    return env('SLACK_WEBHOOK_URL');
}

Sending Notifications

You can send the notification using the Notification façade, where the first parameter is the entity to the notified (notifiable) and the second parameter is a notification instance:

Notification::send(Admin::first(), new TodoCompleted($task));

Note: You can either notify a single model instance, or you can notify a whole collection using the façade.

Alternatively, you can use the notify() method on your model that imports the Notifiable trait (which the default User class already does out of the box):

$admin->notify(new TodoCompleted($task));

Queueing Notifications

Note: Before queueing notifications you should configure your queue and start a worker.

Queueing helps speed up your app’s response time when sending notifications, as many times, external API calls need to be made to deliver the notifications.

Notifications can be queued by adding the ShouldQueue interface and Queueable trait to your class like so:

class NewUser extends Notification implements ShouldQueue
{
    use Queueable;

Once this is done, Laravel will detect the ShouldQueue interface and automatically queue your notifications when you send them, instead of sending them synchronously. You can read more on Queuing and Delaying here.

Conclusion…

Notifications are pretty neat, and their ‘notifying powers’ are only limited by your imagination. You can get a clearer understanding of the other notification channels by checking out the docs. Matt Stauffer also wrote a great post on it here.

✌🏼