Notifications

Masonite has a simple yet powerful notification feature which is used to send notifications from your application. Here is a brief overview of what you can do with notifications:

  • Send E-mail, Slack and SMS notifications

  • Store notifications in a database so they may be displayed in your web interface.

  • Queue notifications

  • Broadcast notifications

Creating a Notification

To create and send a notification with Masonite, you must first build a Notification class. This class will act as the settings for your notification such as the delivery channels and the content of the notification for those different channels (mail, slack, sms, ...).

The first step of building a notification is running the command:

$ python craft notification Welcome

This will create your notification and it will look something like this:

class Welcome(Notification, Mailable):

    def to_mail(self, notifiable):
        return (
            self.to(notifiable.email)
            .subject("Welcome to our site!")
            .from_("[email protected]")
            .text(f"Hello {notifiable.name}")
        )

    def via(self, notifiable):
        return ["mail"]

Each notification class has a via method that specify on which channels the notification will be delivered. Notifications may be sent on the mail, database, broadcast, slack and vonage channels. More details on this later. When sending the notification it will be automatically sent to each channel.

If you would like to use an other delivery channel, feel free to check if a community driver has been developed for it or create your own driver and share it with the community !

via method should returns a list of the channels you want your notification to be delivered on. This method receives a notifiable instance.

Sending a Notification

Basic

You can send your notification inside your controller easily by using the Notification class:

If the notification needs to be delivered to multiple channels you can chain the different routes:

To notifiables

If you want to send notifications e.g. to your users inside your application, you can define them as notifiables. Then you can still use Notification class to send notification:

Or you can use a handy notify() method:

Using Notifiables

ORM Models can be defined as Notifiable to allow notifications to be sent to them. The most common use case is to set User model as Notifiable as we often need to send notifications to users.

To set a Model as Notifiable, just add the Notifiable mixin to it:

You can now send notifications to it with user.notify() method.

Routing

Then you can define how notifications should be routed for the different channels. This is always done by defining a route_notification_for_{driver} method.

For example, with mail driver you can define:

This is actually the default behaviour of the mail driver so you won't have to write that but you can customize it to your needs if your User model don't have email field or if you want to add some logic to get the recipient email.

Queueing Notifications

If you would like to queue the notification then you just need to inherit the Queueable class and it will automatically send your notifications into the queue to be processed later. This is a great way to speed up your application:

Channels

Mail

You should define a to_mail method on the notification class to specify how to build the email notification content.

The notification will be sent using the default mail driver defined in config/mail.py. For more information about options to build mail notifications, please check out Mailable options.

If you want to override the mail driver for a given notification you can do:

Slack

You should define a to_slack method on the notification class to specify how to build the slack notification content.

Options

SlackComponent takes different options to configure your notification:

Method
Description
Example

.text()

The text you want to show in the message

.text('Welcome to Masonite!')

.to()

The channel you want to broadcast to. If the value you supply starts with a # sign then Notifications will make a POST request with your token to the Slack channel list API and get the channel ID. You can specify the channel ID directly if you don't want this behavior

.to('#general') .to('CHSUU862')

.send_from()

The username you want to show as the message sender. You can also specify either the url or icon that will be displayed as the sender.

.send_from('Masonite Bot', icon="👻")

.as_current_user()

This sets a boolean value to True on whether the message should show as the currently authenticated user.

.as_current_user()

.link_names()

This enables finding and linking channel names and usernames in message.

.link_names()

.can_reply()

This auhtorizes replying back to the message.

.can_reply()

.without_markdown()

This will not parse any markdown in the message. This is a boolean value and requires no parameters.

.without_markdown()

.unfurl_links()

This enable showing message attachments and links previews. Usually slack will show an icon of the website when posting a link. This enables that feature for the current message.

.unfurl_links()

.as_snippet()

Used to post the current message as a snippet instead of as a normal message. This option has 3 keyword arguments. The file_type, name, and title. This uses a different API endpoint so some previous methods may not be used.

.as_snippet(file_type='python', name='snippet', title='Awesome Snippet')

.token()

Override the globally configured token.

.token('xoxp-359926262626-35...')

Notifications can be sent to a Slack workspace in two ways in Masonite:

Incoming Webhooks

You will need to configure an "Incoming Webhook" integration for your Slack workspace. This integration will provide you with a URL you may use when routing Slack notifications. This URL will target a specific Slack channel.

Web API

You will need to generate a token to interact with your Slack workspace.

This token should have at minimum the channels:read, chat:write:bot, chat:write:user and files:write:user permission scopes. If your token does not have these scopes then parts of this feature will not work.

Then you can define this token globally in config/notifications.py file as SLACK_TOKEN environment variable. Or you can configure different tokens (with eventually different scopes) per notifications.

Advanced Formatting

Slack notifications can use Slack Blocks Kit to build more complex notifications. Before using this you just have to install slackblocks python API to handle Block Kit formatting.

Then you can import most of the blocks available in Slack documentation and start building your notification. You need to use the block() option. Once again you can chain as many blocks as you want.

You can find all blocks name and options in slackblocks documentation and more information in Slack blocks list.

Routing to notifiable

You should define the related route_notification_for_slack method on your notifiable to return either

  • a webhook URL or a list of webhook URLs (if you're using Incoming Webhooks)

  • a channel name/ID or a list of channels names/IDs (if you're using Slack Web API)

Routing to anonymous

To send a Slack notification without having a notifiable entity you must use the route method

The second parameter can be a channel name, a channel IDor a webhook URL.

SMS

Sending SMS notifications in Masonite is powered by Vonage (formerly Nexmo). Before you can send notifications via Vonage, you need to install the vonage Python client.

Then you should configure the VONAGE_KEY and VONAGE_SECRET credentials in notifications.py configuration file:

You can also define (globally) sms_from which is the phone number or name that your SMS will be sent from. You can generate a phone number for your application in the Vonage dashboard.

You should define a to_vonage method on the notification class to specify how to build the sms notification content.

Options

If the SMS notification contains unicode characters, you should call the unicode method when constructing the notification

The global sms_from number can be overriden inside the notification class:

Routing to notifiable

You should define the related route_notification_for_vonage method on your notifiable to return a phone number or a list of phone numbers to send the notification to.

Routing to anonymous

To send a SMS notification without having a notifiable entity you must use the route method

Saving notifications

Notifications can be stored in your application database when sent to Notifiable entities. The notification is stored in a notifications table. This table will contain information such as the notification type as well as a JSON data structure that describes the notification.

To store a notification in the database you should define a to_database method on the notification class to specify how to build the notification content that will be persisted.

This method should return str, dict or JSON data (as it will be saved into a TEXT column in the notifications table). You also need to add database channel to the via method to enable database notification storage.

Initial setup

Before you can store notifications in database you must create the database notifications table.

Then you can migrate your database

The ORM Model describing a Notification is DatabaseNotification and has the following fields:

  • id is the primary key of the model (defined with UUID4)

  • type will store the notification type as a string (e.g. WelcomeNotification)

  • read_at is the timestamp indicating when notification has been read

  • data is the serialized representation of to_database()

  • notifiable is the relationship returning the Notifiable entity a notification belongs to (e.g. User)

  • created_at, updated_at timestamps

Querying notifications

A notifiable entity has a notifications relationship that will returns the notifications for the entity:

You can directly get the unread/read notifications:

Managing notifications

You can mark a notification as read or unread with the following mark_as_read and mark_as_unread methods

Finally, keep in mind that database notifications can be used as any Masonite ORM models, meaning you can for example make more complex queries to fetch notifications, directly on the model.

Broadcasting Notifications

If you would like to broadcast the notification then you need to:

  • inherit the CanBroadcast class and specify the broadcast_on method

  • define a to_broadcast method on the notification class to specify how to build the notification content that will be broadcasted

Broadcasting to notifiables

By default notifications will be broadcasted to channel(s) defined in broadcast_on method but you can override this per notifiable by implementing route_notification_for_broadcast method on your notifiable:

Broadcasting to anonymous

Adding a new driver

Masonite ships with a handful of notification channels, but you may want to write your own drivers to deliver notifications via other channels. Masonite makes this process simple.

Creating the driver

Two methods need to be implemented in order to create a notification driver: send and queue.

get_data() method will be available and will return the data defined in the to_voice() method of the notification.

Registering the driver

As any drivers it should be registered, through a custom provider for example:

Then you could scaffold this code into a new Masonite package so that community can use it 😉 !

Advanced Usage

Dry run

You can enable dry notifications to avoid notifications to be sent. It can be useful in some cases (background task, production commands, development, testing...)

Ignoring errors

When fail_silently parameter is enabled, notifications sending will not raise exceptions if an error occurs.

Overriding channels

Channels defined in via() method of the notification can be overriden at send:

Using channels parameter we can send to other channels (if correctly defined in notification class):

Last updated