tobento/service-notifier

Notifier interface for PHP applications.

1.0.2 2024-03-22 16:09 UTC

This package is auto-updated.

Last update: 2024-05-22 16:32:36 UTC


README

Notifier interface for PHP applications using Symfony Notifier as default implementation.

Table of Contents

Getting started

Add the latest version of the notifier service project running this command.

composer require tobento/service-notifier

Requirements

  • PHP 8.0 or greater

Highlights

  • Framework-agnostic, will work with any project
  • Decoupled design

Documentation

Basic Usage

Creating And Sending Notifications

Once you have created the notifier you can create and send notifications:

use Tobento\Service\Notifier\NotifierInterface;
use Tobento\Service\Notifier\Notification;
use Tobento\Service\Notifier\Recipient;

class SomeService
{
    public function send(NotifierInterface $notifier): void
    {
        // Create a Notification that has to be sent:
        // using the "mail" and "sms" channel
        $notification = (new Notification(subject: 'New Invoice', channels: ['mail', 'sms']))
            ->content('You got a new invoice for 15 EUR.');

        // The receiver of the notification:
        $recipient = new Recipient(
            email: 'mail@example.com',
            phone: '15556666666',
        );

        // Send the notification to the recipient:
        $notifier->send($notification, $recipient);
    }
}

Check out the Notifications section to learn more about the available notifications you can create or you might create your own notification class fitting your application.

Check out the Recipients section to learn more about the available recipients you can create or you might create your own recipient class fitting your application.

Notifier

Create Notifier

use Tobento\Service\Notifier\NotifierInterface;
use Tobento\Service\Notifier\Notifier;
use Tobento\Service\Notifier\ChannelsInterface;
use Tobento\Service\Notifier\Channels;
use Tobento\Service\Notifier\QueueHandlerInterface;

$notifier = new Notifier(
    channels: new Channels(), // ChannelsInterface
    
    // you may set a queue handler if you want to support queuing notifications:
    queueHandler: null, // null|QueueHandlerInterface
    
    // you may set an event dispatcher if you want to support events:
    eventDispatcher: null, // null|EventDispatcherInterface
);

var_dump($notifier instanceof NotifierInterface);
// bool(true)

Check out the Channels section to learn more about the available channels.

Notifications

Notification

The Notification::class may be used to create simple notification messages supporting all channels.

use Tobento\Service\Notifier\Notification;

$notification = new Notification(
    subject: 'New Invoice',
    content: 'You got a new invoice for 15 EUR.',
    channels: ['mail', 'sms'],
);

If you want to support custom channels you may consider creating a custom notification!

Available methods

use Tobento\Service\Notifier\Notification;

$notification = (new Notification())
    // you may prefer using the subject method:
    ->subject('New Invoice')
    // you may prefer using the content method:
    ->content('You got a new invoice for 15 EUR.')
    // you may specify a name for any later usage:
    ->name('New Invoice');

In addition, you may add messages for specific channels:

use Tobento\Service\Notifier\Notification;
use Tobento\Service\Notifier\Message;

$notification = (new Notification(
    subject: 'General subject used if no specific message',
    channels: ['mail', 'sms'],
))
->addMessage('sms', new Message\Sms(
    subject: 'Specific sms message',
))
// or specific sms channel:
->addMessage('sms/vonage', new Message\Sms(
    subject: 'Specific sms message',
));

Abstract Notification

Use the AbstractNotification::class if you want to create specific messages for each channel.

Simply extend from the AbstractNotification::class and add the message interfaces with its method you want to support.

Furthermore, any to methods such as toSms will receive a $recipient entity, the $channel name and you may request any service being resolved (autowired) by the container.

use Tobento\Service\Notifier\AbstractNotification;
use Tobento\Service\Notifier\RecipientInterface;
use Tobento\Service\Notifier\Message;

class OrderNotification extends AbstractNotification implements Message\ToSms
{
    /**
     * Create an order notification.
     *
     * @param Order $order
     */
    public function __construct(
        protected Order $order,
    ) {}
    
    /**
     * Returns the sms message.
     *
     * @param RecipientInterface $recipient
     * @param string $channel The channel name.
     * @return Message\SmsInterface
     */
    public function toSms(RecipientInterface $recipient, string $channel, SomeService $service): Message\SmsInterface
    {
        return new Message\Sms(
            subject: sprintf('Thanks for your order %s', $this->order->name),
        );
    }
}

Recipients

Recipient

The Recipient::class may be used to create a recipient supporting all channels.

use Tobento\Service\Notifier\Recipient;

$recipient = new Recipient(
    email: 'mail@example.com', // null|string
    phone: '15556666666', // null|string
    id: 'unique-id', // null|string|int
    type: 'users', // null|string
    locale: 'en', // string (en default)
    // you may set the channels the recipient prefers:
    channels: [],
);

// you may add specific addresses:
$recipient->addAddress(
    channel: 'chat/slack',
    address: ['key' => 'value'] // mixed
);

User Recipient

The UserRecipient::class may be used if you have installed the User Service.

use Tobento\Service\Notifier\UserRecipient;
use Tobento\Service\User\UserInterface;

$recipient = new UserRecipient(
    user: $user, // UserInterface
    channels: [],
);

Channel

Mail Channel

The mail channel uses the Mail Service to send notifications.

use Tobento\Service\Notifier\Mail;
use Tobento\Service\Notifier\ChannelInterface;
use Tobento\Service\Mail\MailerInterface;
use Psr\Container\ContainerInterface;

$channel = new Mail\Channel(
    name: 'mail',
    mailer: $mailer, // MailerInterface
    container: $container, // ContainerInterface
);

var_dump($channel instanceof ChannelInterface);
// bool(true)

Mail Notification

To send mail notifications you have multiple options:

Using the Abstract Notification

Simply extend from the AbstractNotification::class and implement the ToMail interface. The interface requires a toMailHandler method which is already added on the AbstractNotification::class defining the toMail method as the message handler. You will just need to add the toMail method which will receive a $recipient entity, the $channel name and you may request any service being resolved (autowired) by the container.

use Tobento\Service\Notifier\AbstractNotification;
use Tobento\Service\Notifier\RecipientInterface;
use Tobento\Service\Notifier\Message\ToMail;
use Tobento\Service\Mail\Message;

class SampleNotification extends AbstractNotification implements ToMail
{
    /**
     * Returns the mail message.
     *
     * @param RecipientInterface $recipient
     * @param string $channel The channel name.
     * @return Message
     */
    public function toMail(RecipientInterface $recipient, string $channel, SomeService $service): Message
    {
        return (new Message())
            // not required if none is defined, the address will be added on sending:
            ->to('to@example.com')
            
            ->subject('Subject')
            //->textTemplate('welcome-text')
            //->htmlTemplate('welcome')
            //->text('Lorem Ipsum')
            ->html('<p>Lorem Ipsum</p>');
    }
}

If you do not have defined a default from address, you will need to set it on each message:

use Tobento\Service\Mail\Message;

$message = (new Message())
    ->from('from@example.com');

Using the Notification

use Tobento\Service\Notifier\Notification;
use Tobento\Service\Mail;

$notification = new Notification(
    subject: 'New Invoice',
    content: 'You got a new invoice for 15 EUR.',
);
    
// with specific mail message:
$notification = (new Notification())
    ->addMessage('mail', (new Mail\Message())
        ->subject('Subject')
        ->html('<p>Lorem Ipsum</p>')
    );

Check out the Mail Message section to learn more about mail messages.

Mail Recipient

When sending notifications via the mail channel, the channel will call the getAddressForChannel method on the recipient entity to get the email address when no were defined on the mail message.

use Tobento\Service\Notifier\Recipient;
use Tobento\Service\Notifier\Address;
use Tobento\Service\Notifier\Notification;

$recipient = new Recipient(
    email: 'mail@example.com',
    // or
    email: new Address\Email('mail@example.com', 'Name'),
);

$address = $recipient->getAddressForChannel('mail', new Notification('subject'));

var_dump($address instanceof Address\EmailInterface);
// bool(true)

Mail Channel Factory

use Tobento\Service\Notifier\Mail\ChannelFactory;
use Tobento\Service\Notifier\ChannelInterface;
use Tobento\Service\Mail\MailerInterface;
use Psr\Container\ContainerInterface;

$factory = new ChannelFactory(
    mailer: $mailer, // MailerInterface
    container: $container, // ContainerInterface
);

$channel = $factory->createChannel(name: 'mail');

// using a specific mailer:
$channel = $factory->createChannel(name: 'mail/mailchimp', config: [
    'mailer' => 'mailchimp',
]);

var_dump($channel instanceof ChannelInterface);
// bool(true)

Sms Channel

Use the ChannelAdapter::class to create a SMS channel using the Symfony SMS Channel:

You will need to install any chat service you would like composer require symfony/vonage-notifier e.g.

use Tobento\Service\Notifier\Symfony\ChannelAdapter;
use Tobento\Service\Notifier\ChannelInterface;
use Psr\Container\ContainerInterface;

$channel = new ChannelAdapter(
    name: 'sms/vonage',
    channel: new \Symfony\Component\Notifier\Channel\SmsChannel(
        transport: new \Symfony\Component\Notifier\Bridge\Vonage\VonageTransport(
            apiKey: '******',
            apiSecret: '******',
            from: 'FROM',
        )
    ),
    container: $container, // ContainerInterface
);

var_dump($channel instanceof ChannelInterface);
// bool(true)

Sms Notification

To send SMS notifications you have multiple options:

Using the Abstract Notification

Simply extend from the AbstractNotification::class and implement the ToSms interface. The interface requires a toSmsHandler method which is already added on the AbstractNotification::class defining the toSms method as the message handler. You will just need to add the toSms method which will receive a $recipient entity, the $channel name and you may request any service being resolved (autowired) by the container.

use Tobento\Service\Notifier\AbstractNotification;
use Tobento\Service\Notifier\RecipientInterface;
use Tobento\Service\Notifier\Message;

class SampleNotification extends AbstractNotification implements Message\ToSms
{
    /**
     * Returns the sms message.
     *
     * @param RecipientInterface $recipient
     * @param string $channel The channel name.
     * @return Message\SmsInterface
     */
    public function toSms(RecipientInterface $recipient, string $channel): Message\SmsInterface
    {
        return new Message\Sms(
            subject: 'Sms message',
        );
        
        // you may set a specific to address:
        return new Message\Sms(
            subject: 'Sms message',
            to: $recipient->getAddressForChannel('sms/vonage'),
        );
    }
}

Using the Notification

use Tobento\Service\Notifier\Notification;
use Tobento\Service\Notifier\Message;

$notification = new Notification(
    subject: 'New Invoice',
    content: 'You got a new invoice for 15 EUR.',
);
    
// with specific sms message:
$notification = (new Notification())
    ->addMessage('sms', new Message\Sms(
        subject: 'Sms message',
    ));

Sms Recipient

When sending notifications via the sms channel, the channel will call the getAddressForChannel method on the recipient entity to get the sms address when no specific were defined.

use Tobento\Service\Notifier\Recipient;
use Tobento\Service\Notifier\Address;
use Tobento\Service\Notifier\Notification;

$recipient = new Recipient(
    phone: '15556666666',
    // or
    phone: new Address\Phone('15556666666', 'Name'),
);

$address = $recipient->getAddressForChannel('sms', new Notification('subject'));

var_dump($address instanceof Address\PhoneInterface);
// bool(true)

Chat Channel

Use the ChannelAdapter::class to create a chat channel using the Symfony Chat Channel:

You will need to install any chat service you would like composer require symfony/slack-notifier e.g.

use Tobento\Service\Notifier\Symfony\ChannelAdapter;
use Tobento\Service\Notifier\ChannelInterface;
use Psr\Container\ContainerInterface;

$channel = new ChannelAdapter(
    name: 'chat/slack',
    channel: new \Symfony\Component\Notifier\Channel\ChatChannel(
        transport: new \Symfony\Component\Notifier\Bridge\Slack\SlackTransport(
            accessToken: '******',
        )
    ),
    container: $container, // ContainerInterface
);

var_dump($channel instanceof ChannelInterface);
// bool(true)

Chat Notification

To send chat notifications you have multiple options:

Using the Abstract Notification

Simply extend from the AbstractNotification::class and implement the ToChat interface. The interface requires a toChatHandler method which is already added on the AbstractNotification::class defining the toChat method as the message handler. You will just need to add the toChat method which will receive a $recipient entity, the $channel name and you may request any service being resolved (autowired) by the container.

use Tobento\Service\Notifier\AbstractNotification;
use Tobento\Service\Notifier\RecipientInterface;
use Tobento\Service\Notifier\Message;
use Tobento\Service\Notifier\Symfony\MessageOptions;
use Symfony\Component\Notifier\Bridge\Slack\SlackOptions;

class SampleNotification extends AbstractNotification implements Message\ToChat
{
    /**
     * Returns the chat message.
     *
     * @param RecipientInterface $recipient
     * @param string $channel The channel name.
     * @return Message\ChatInterface
     */
    public function toChat(RecipientInterface $recipient, string $channel): Message\ChatInterface
    {
        if ($channel === 'chat/slack') {
            // you may set message options:
            $options = new SlackOptions();

            return new (Message\Chat('Chat message'))
                ->parameter(new MessageOptions($options));
        }
        
        // for any other chat channel:
        return new Message\Chat(
            subject: 'Chat message',
        );
    }
}

Using the Notification

use Tobento\Service\Notifier\Notification;
use Tobento\Service\Notifier\Message;

$notification = new Notification(
    subject: 'New Invoice',
    content: 'You got a new invoice for 15 EUR.',
);
    
// with specific chat message:
$notification = (new Notification())
    ->addMessage('chat/slack', new Message\Chat(
        subject: 'Chat message',
    ));

Chat Recipient

When sending notifications via the chat channel, you may add a specific channel address with parameters for later usage.

use Tobento\Service\Notifier\Recipient;
use Tobento\Service\Notifier\Address;
use Tobento\Service\Notifier\Notification;

$recipient = (new Recipient())
    ->addAddress('chat/slack', ['channel' => 'name']);

$address = $recipient->getAddressForChannel('chat/slack', new Notification('subject'));

var_dump($address);
// array(1) { ["channel"]=> string(4) "name" }

Sample notification with address usage

use Tobento\Service\Notifier\AbstractNotification;
use Tobento\Service\Notifier\RecipientInterface;
use Tobento\Service\Notifier\Message;
use Tobento\Service\Notifier\Symfony\MessageOptions;
use Symfony\Component\Notifier\Bridge\Slack\SlackOptions;

class SampleNotification extends AbstractNotification implements Message\ToChat
{
    /**
     * Returns the chat message.
     *
     * @param RecipientInterface $recipient
     * @param string $channel The channel name.
     * @return Message\ChatInterface
     */
    public function toChat(RecipientInterface $recipient, string $channel): Message\ChatInterface
    {
        if ($channel === 'chat/slack') {
            $address = $recipient->getAddressForChannel('chat/slack', $this);
            
            $options = new SlackOptions([
                'recipient_id' => $address['channel'] ?? null,
            ]);

            return new (Message\Chat('Chat message'))
                ->parameter(new MessageOptions($options));
        }
        
        // for any other chat channel:
        return new Message\Chat(
            subject: 'Chat message',
        );
    }
}

Push Channel

Use the ChannelAdapter::class to create a push channel using the Symfony Push Channel:

You will need to install any push service you would like composer require symfony/one-signal-notifier e.g.

use Tobento\Service\Notifier\Symfony\ChannelAdapter;
use Tobento\Service\Notifier\ChannelInterface;
use Psr\Container\ContainerInterface;

$channel = new ChannelAdapter(
    name: 'push/one-signal',
    channel: new \Symfony\Component\Notifier\Channel\ChatChannel(
        transport: new \Symfony\Component\Notifier\Bridge\OneSignal\OneSignalTransport(
            appId: '******',
            apiKey: '******',
        )
    ),
    container: $container, // ContainerInterface
);

var_dump($channel instanceof ChannelInterface);
// bool(true)

Push Notification

To send push notifications you have multiple options:

Using the Abstract Notification

Simply extend from the AbstractNotification::class and implement the ToPush interface. The interface requires a toPushHandler method which is already added on the AbstractNotification::class defining the toPush method as the message handler. You will just need to add the toPush method which will receive a $recipient entity, the $channel name and you may request any service being resolved (autowired) by the container.

use Tobento\Service\Notifier\AbstractNotification;
use Tobento\Service\Notifier\RecipientInterface;
use Tobento\Service\Notifier\Message;
use Tobento\Service\Notifier\Symfony\MessageOptions;
use Symfony\Component\Notifier\Bridge\OneSignal\OneSignalOptions;

class SampleNotification extends AbstractNotification implements Message\ToPush
{
    /**
     * Returns the push message.
     *
     * @param RecipientInterface $recipient
     * @param string $channel The channel name.
     * @return Message\PushInterface
     */
    public function toPush(RecipientInterface $recipient, string $channel): Message\PushInterface
    {
        if ($channel === 'push/one-signal') {
            // you may set message options:
            $options = new OneSignalOptions([]);

            return new (Message\Push('Push subject'))
                ->content('Push content')
                ->parameter(new MessageOptions($options));
        }
        
        // for any other push channel:
        return new Message\Push(
            subject: 'Push subject',
            content: 'Push content',
        );
    }
}

Using the Notification

use Tobento\Service\Notifier\Notification;
use Tobento\Service\Notifier\Message;

$notification = new Notification(
    subject: 'New Invoice',
    content: 'You got a new invoice for 15 EUR.',
);
    
// with specific chat message:
$notification = (new Notification())
    ->addMessage('push/one-signal', new Message\Push(
        subject: 'Push subject',
        content: 'Push content',
    ));

Push Recipient

When sending notifications via the push channel, you may add a specific channel address with parameters for later usage.

use Tobento\Service\Notifier\Recipient;
use Tobento\Service\Notifier\Address;
use Tobento\Service\Notifier\Notification;

$recipient = (new Recipient())
    ->addAddress('push/one-signal', ['recipient_id' => 'id']);

$address = $recipient->getAddressForChannel('push/one-signal', new Notification('subject'));

var_dump($address);
// array(1) { ["recipient_id"]=> string(2) "id" }

Sample notification with address usage

use Tobento\Service\Notifier\AbstractNotification;
use Tobento\Service\Notifier\RecipientInterface;
use Tobento\Service\Notifier\Message;
use Tobento\Service\Notifier\Symfony\MessageOptions;
use Symfony\Component\Notifier\Bridge\OneSignal\OneSignalOptions;

class SampleNotification extends AbstractNotification implements Message\ToPush
{
    /**
     * Returns the push message.
     *
     * @param RecipientInterface $recipient
     * @param string $channel The channel name.
     * @return Message\PushInterface
     */
    public function toPush(RecipientInterface $recipient, string $channel): Message\PushInterface
    {
        if ($channel === 'push/one-signal') {
            $address = $recipient->getAddressForChannel('push/one-signal', $this);
            
            $options = new OneSignalOptions([
                'recipient_id' => $address['recipient_id'] ?? null,
            ]);

            return new (Message\Push('Push subject'))
                ->content('Push content')
                ->parameter(new MessageOptions($options));
        }
        
        // for any other push channel:
        return new Message\Push(
            subject: 'Push subject',
            content: 'Push content',
        );
    }
}

Storage Channel

The storage channel stores the notification information in the configured storage repository.

use Tobento\Service\Notifier\Storage;
use Tobento\Service\Notifier\ChannelInterface;
use Tobento\Service\Repository\RepositoryInterface;
use Psr\Container\ContainerInterface;

$channel = new Storage\Channel(
    name: 'storage/database',
    repository: $repository, // RepositoryInterface
    container: $container, // ContainerInterface
);

var_dump($channel instanceof ChannelInterface);
// bool(true)

Check out the Repository Service to learn more about it.

The storage needs to have the following table columns:

Column Type Description
id bigint(21) primary key -
name varchar(255) Used to store the notification name
recipient_id varchar(36) Used to store the recipient id
recipient_type varchar(255) Used to store the recipient type
data json Used to store the message data
read_at datetime Used to store date read at
created_at datetime Used to store date created at

Storage Repository

You may use the provided StorageRepository::class as repository implementation:

You will need to install the service:

composer require tobento/service-repository-storage

use Tobento\Service\Notifier\Storage;
use Tobento\Service\Notifier\ChannelInterface;
use Tobento\Service\Repository\RepositoryInterface;
use Tobento\Service\Storage\StorageInterface;
use Psr\Container\ContainerInterface;

$channel = new Storage\Channel(
    name: 'storage/database',
    repository: new StorageRepository(
        storage: $storage, // StorageInterface
        table: 'notifications',
    ),
    container: $container, // ContainerInterface
);

Check out the Storage Service - Storages for the available storages.

Check out the Repository Storage Service to learn more about it in general.

Storage Notification

To send Storage notifications you have multiple options:

Using the Abstract Notification

Simply extend from the AbstractNotification::class and implement the ToStorage interface. The interface requires a toStorageHandler method which is already added on the AbstractNotification::class defining the toStorage method as the message handler. You will just need to add the toStorage method which will receive a $recipient entity, the $channel name and you may request any service being resolved (autowired) by the container.

use Tobento\Service\Notifier\AbstractNotification;
use Tobento\Service\Notifier\RecipientInterface;
use Tobento\Service\Notifier\Message;

class SampleNotification extends AbstractNotification implements Message\ToStorage
{
    /**
     * Returns the storage message.
     *
     * @param RecipientInterface $recipient
     * @param string $channel The channel name.
     * @return Message\StorageInterface
     */
    public function toStorage(RecipientInterface $recipient, string $channel): Message\StorageInterface
    {
        return new Message\Storage(data: [
            'order_id' => $this->order->id,
        ]);
    }
}

Using the Notification

use Tobento\Service\Notifier\Notification;
use Tobento\Service\Notifier\Message;

$notification = new Notification(
    subject: 'New Invoice',
    content: 'You got a new invoice for 15 EUR.',
);
    
// with specific storage message:
$notification = (new Notification())
    ->addMessage('storage', new Message\Storage([
        'foo' => 'bar',
    ]));

Storage Recipient

When sending notifications via the storage channel, the channel will store the $recipient->getId() and $recipient->getType() values which you can later use to fetch notifications:

// channel will store on sending:
$repository->create([
    'name' => $notification->getName(),
    'recipient_id' => $recipient->getId(),
    'recipient_type' => $recipient->getType(),
    'data' => $message->getData(),
    'read_at' => null,
    'created_at' => null,
]);

Accessing Storage Notifications

Once notifications are stored, you can retrieve the notifications using the repository from the channel:

$channel = $channels->get(name: 'storage/database');

$entities = $channel->repository()->findAll(where: [
    'recipient_id' => $userId,
    //'recipient_type' => 'user',
]);

Channels

Default Channels

use Tobento\Service\Notifier\Channels;
use Tobento\Service\Notifier\ChannelsInterface;
use Tobento\Service\Notifier\ChannelInterface;

$channels = new Channels(
    $channel, // ChannelInterface
    $anotherChannel, // ChannelInterface
);

var_dump($channels instanceof ChannelsInterface);
// bool(true)

Lazy Channels

The LazyChannels::class creates the channels only on demand.

use Tobento\Service\Notifier\LazyQueues;
use Tobento\Service\Notifier\ChannelsInterface;
use Tobento\Service\Notifier\ChannelInterface;
use Tobento\Service\Notifier\ChannelFactoryInterface;
use Tobento\Service\Notifier\Symfony;
use Psr\Container\ContainerInterface;

$channels = new LazyChannels(
    container: $container, // ContainerInterface
    channels: [
        // using a factory:
        'sms' => [
            // factory must implement ChannelFactoryInterface
            'factory' => Symfony\ChannelFactory::class,
            'config' => [
                'dsn' => 'vonage://KEY:SECRET@default?from=FROM',
                'channel' => \Symfony\Component\Notifier\Channel\SmsChannel::class,
            ],
        ],
        
        // using a closure:
        'mail' => static function (string $name, ContainerInterface $c): ChannelInterface {
            // create channel ...
            return $channel;
        },
        
        // or you may sometimes just create the channel (not lazy):
        'sms/null' => new NullChannel(name: 'sms'),
    ],
);

var_dump($channels instanceof ChannelsInterface);
// bool(true)

Queue

You may queue your notification by just adding the Queue::class parameter:

use Tobento\Service\Notifier\Notification;
use Tobento\Service\Notifier\Parameter\Queue;

$notification = (new Notification())
    ->parameter(new Queue(
        // you may specify the queue to be used:
        name: 'secondary',
        
        // you may specify a delay in seconds:
        delay: 30,
        
        // you may specify how many times to retry:
        retry: 3,
        
        // you may specify a priority:
        priority: 100,
        
        // you may specify if you want to encrypt the message:
        encrypt: true,
    ));

Requirements

To support queuing notifications you will need to pass a queue handler to the notifier.

Consider using the default queue handler using the Queue Service:

First, install the queue service:

composer require tobento/service-queue

Finally, pass the queue handler to the notifier:

use Tobento\Service\Notifier\NotifierInterface;
use Tobento\Service\Notifier\Notifier;
use Tobento\Service\Notifier\ChannelsInterface;
use Tobento\Service\Notifier\Channels;
use Tobento\Service\Notifier\Queue\QueueHandler;
use Tobento\Service\Queue\QueueInterface;

$notifier = new Notifier(
    channels: new Channels(), // ChannelsInterface
    
    // set a queue handler:
    queueHandler: new QueueHandler(
        queue: $queue, // QueueInterface
        // you may define the default queue used if no specific is defined on the notification.
        queueName: 'mails', // null|string
    ),
);

Events

You may listen to the following events if your notifier is configured to support it.

Event Description
Tobento\Service\Notifier\Event\NotificationSending::class The Event will be fired before sending the notification.
Tobento\Service\Notifier\Event\NotificationSent::class The Event is fired after the notification is sent.
Tobento\Service\Notifier\Event\NotificationQueued::class The Event will be fired after queuing the notification.

When using the default notifier just pass an event dispatcher.

Credits