Sending Slack Notifications from Your Laravel App
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.
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<?phpnamespace 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 toArray
method 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:
<?phpnamespace 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:
<?phpnamespace 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.