Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/chijioke-ibekwe/raven

Laravel multi-channel notification package
https://github.com/chijioke-ibekwe/raven

amazon-ses laravel laravel-framework laravel-package notifications php php-package sendgrid sendgrid-api

Last synced: about 4 hours ago
JSON representation

Laravel multi-channel notification package

Awesome Lists containing this project

README

        

#

Raven

[![Status](https://img.shields.io/badge/status-active-success.svg)]()
[![GitHub Issues](https://img.shields.io/github/issues/chijioke-ibekwe/The-Documentation-Compendium.svg)](https://github.com/chijioke-ibekwe/raven/issues)
[![GitHub Pull Requests](https://img.shields.io/github/issues-pr/chijioke-ibekwe/The-Documentation-Compendium.svg)](https://github.com/chijioke-ibekwe/raven/pulls)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](/LICENSE)

---

Multi-channel Laravel notification package


## 📝 Table of Contents

- [About](#about)
- [Getting Started](#getting_started)
- [Usage](#usage)
- [Built Using](#built_using)
- [TODO](#todo)
- [Authors](#authors)

## 🧐 About
In Laravel, crafting notification classes can often feel repetitive (and WET), especially in projects that rely
heavily on notifications. Meet Raven – the solution that simplifies the process of sending notifications through
multiple channels in Laravel, allowing you to focus on your peculiar business logic. Currently, Raven seamlessly handles
email notifications through SendGrid and Amazon SES, as well as database/in-app notifications. Stay tuned, as support for SMS
notifications will be integrated in the near future.

## 🏁 Getting Started

### Prerequisites
To use this package, you need the following requirements:

1. PHP >= v8.0
2. Laravel >= v8.0
3. Composer

## 🎈 Usage
1. You can install this package via Composer using the command:
```bash
composer require chijioke-ibekwe/raven
```

2. Next, you will need to publish and run the migration files, and the config file. The following command will allow you
do all of the above:
```bash
php artisan raven:install
```

3. The migrations will be published in your project's migrations directory `./database/migrations` while the config file
`raven.php`, will be published in your config directory `./config`. Content of the config file is as shown below:
```php
[
'email' => env('EMAIL_NOTIFICATION_PROVIDER', 'sendgrid'),
'sms' => env('SMS_NOTIFICATION_PROVIDER', 'vonage')
],

'providers' => [
'sendgrid' => [
'key' => env('SENDGRID_API_KEY')
],
'ses' => [
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'template_source' => env('AWS_SES_TEMPLATE_SOURCE', 'sendgrid')
]
],

'customizations' => [
'mail' => [
'from' => [
'address' => env('MAIL_FROM_ADDRESS', '[email protected]'),
'name' => env('MAIL_FROM_NAME', 'Example'),
]
],
'queue_name' => env('RAVEN_QUEUE_NAME')
'templates_directory' => env('TEMPLATES_DIRECTORY', resource_path('templates'))
],

'api' => [
'prefix' => 'api/v1',
'middleware' => 'api'
]

];
```
- The `default` array allows you to configure your default service providers for your notification channels. Options
are `sendgrid` and `ses`. (`vonage` for SMS will be integrated soon).
- The `providers` array is where you supply the credentials for the service provider you choose. When using `ses`, you
can provide the email template in 2 ways.
- First is by hosting your email template on `sendgrid`. If this is your preferred option, the `templates_source` should be
set as `sendgrid`. NB: For this to work, you need to also provide your credentials for the `sendgrid` provider.
- Second option is by storing your email templates on the file system as .html templates. The `templates_source` in
this case should be set as `filesystem` and the directory of the templates should be provided on the `templates_directory` under `customizations`. (This option is not currently supported for emails, but will be in the near future).
- The `customizations` array allows you to customize your email parameters, optionally your `queue_name` (not
queue connection) for queueing your notifications, and your templates directory.
NB:
- If a queue name is not provided, the default queue will be used.
- The default templates directory is a directory called `templates` in the resources path
- The templates directory set, will contain three directories within: `email` (relevant only if your template source is `filesystem` and provider is `ses`), `sms`, and `in_app`.
- The `email` directory will contain the `.html` templates for your emails.
- The `sms` directory will contain the `.txt` files with the contents of your sms notifications.
- The `in_app` directory will contain `.json` files whose contents will be saved on the data column of the database notifications table.
- All placeholders in these templates should be surrounded by double curly braces e.g `{{name}}`.
- File names of these templates must match the file names in the `email_template_filename`, `sms_template_filename` and `in_app_template_filename` columns on the notification context record.
- The `api` array allows you to customize the provided API routes with prefix and middleware group.

4. After the migrations have been run successfully, you can then proceed to add notification contexts to the database.
To do this, simply create and run migration files similar to the ones below:
- Email Notification Context (when using `sendgrid` as provider or template source)
```php
insertGetId(
array(
'name' => 'user-verified',
'email_template_id' => 'd-ad34ghAwe3mQRvb29',
'description' => 'Notification to inform a user that they have been verified on the platform'
)
);

DB::table('notification_channel_notification_context')->insert(
array(
'notification_channel_id' => 1, //EMAIL
'notification_context_id' => $id
)
);
}

/**
* Reverse the migrations.
*/
public function down(): void
{
DB::table('notification_contexts')->where('name', 'user-verified')->delete();
}
};

```

- Email Notification Context (when using `ses` as provider and `filesystem` as template source)
```php
insertGetId(
array(
'name' => 'user-verified',
'email_template_filename' => 'user-verified.html',
'description' => 'Notification to inform a user that they have been verified on the platform'
)
);

DB::table('notification_channel_notification_context')->insert(
array(
'notification_channel_id' => 1, //EMAIL
'notification_context_id' => $id
)
);
}

/**
* Reverse the migrations.
*/
public function down(): void
{
DB::table('notification_contexts')->where('name', 'user-verified')->delete();
}
};

```

- Database Notification Context
```php
insertGetId(
array(
'name' => 'user-verified',
'description' => 'Notification to inform a user that they have been verified on the platform',
'in_app_template_filename' => 'user-verified.json',
'type' => 'user'
)
);

DB::table('notification_channel_notification_context')->insert(
array(
'notification_channel_id' => 2, //DATABASE
'notification_context_id' => $id
)
);
}

/**
* Reverse the migrations.
*/
public function down(): void
{
DB::table('notification_contexts')->where('name', 'user-verified')->delete();
}
};

```
`user-verified.json`
```json
{
"title": "You have been verified",
"body": "Hello {{name}}. This is to let you know that your account with email {{email}} has been verified",
}
```

- Email and Database Notification Context
```php
insertGetId(
array(
'name' => 'user-verified',
'email_template_id' => 'd-ad34ghAwe3mQRvb29',
'description' => 'Notification to inform a user that they have been verified on the platform',
'in_app_template_filename' => 'user-verified.json',
'type' => 'user'
)
);

DB::table('notification_channel_notification_context')->insert(
array(
array(
'notification_channel_id' => 1, //EMAIL
'notification_context_id' => $id,
),
array(
'notification_channel_id' => 2, //DATABASE
'notification_context_id' => $id,
)
)
);
}

/**
* Reverse the migrations.
*/
public function down(): void
{
DB::table('notification_contexts')->where('name', 'user-verified')->delete();
}
};

```

5. To send a notification at any point in your code, build a `Scroll` object, set the relevant
fields as shown below, and dispatch a `Raven` with the `Scroll`:

```php
$verified_user = User::find(1);
$document_url = "https://example.com/laravel-cheatsheet.pdf";

$scroll = new Scroll();
$scroll->setContextName('user-verified');
$scroll->setRecipients([$verified_user, '[email protected]']);
$scroll->setCcs(['[email protected]' => 'John Doe', '[email protected]' => 'Jane Doe']);
$scroll->setParams([
'id' => $verified_user->id,
'name' => $verified_user->name,
'email' => $verified_user->email
]);
$scroll->setAttachmentUrls($document_url);

Raven::dispatch($scroll);
```
- The `contextName` property is required and must match the notification context name for that notification
on the database.
- The `recipients` property is required and takes any single notifiable/email string, or an array of notifiables/email
strings that should receive the notification.
- The `ccs` property is exclusively for email notifications and takes an array (or associative array with email/name as
key/value pairs respectively) of emails you want to CC on the email notification.
- The `params` property is an associative array of all the variables that exist on the notification
template with their values, where the key must match the variable name on the template.
- Finally, the `attachmentUrls` field takes a url or an array of urls that point to the publicly accessible resource(s) that
needs to be attached to the email notification.

6. To successfully send Database Notifications, it is assumed that the user of this package has already set up a
notifications table in their project via the command below:

```bash
php artisan notifications:table
```
And subsequently:
```bash
php artisan migrate
```
The data column for database notifications using this package, will capture whatever key-value pairs you have in the json template for that notification.
All placeholders surrounded by `{{}}` in the template will be replaced with their values passed in as params of the same name when creating the `Scroll` object.

7. The package takes care of the rest of the logic.

### API
The following API is included in this package for ease of use:
1. `GET /api/v1/notification-contexts`
- Fetches all notification contexts on the database. The user of this API has to be authenticated.
- Return a JSON of the format below:
```json
{
"status": true,
"msg": "Success",
"data": [
{
"id": 1,
"email_template_id": "d-ad34ghAwe3mQRvb29",
"email_template_filename": null,
"name": "user-verified",
"description": "Notification to inform a user that they have been verified on the platform",
"sms_template_filename": null,
"in_app_template_filename": "user-verified.json",
"type": "user",
"active": true,
"notification_channels": [
{
"id": 1,
"type": "EMAIL"
}
]
}
]
}
```
- When user is not authenticated, it returns the following `401` response:
```json
{
"status": false,
"message": "You are not authorized to access this API"
}
```

### Exceptions
The following exceptions can be thrown by the package for the scenarios outlined below:
1. `RavenEntityNotFoundException` `code: 404`
- Dispatching a Raven with a `Scroll` object that has a `contextName` which does not exist on the database.
2. `RavenInvalidDataException` `code: 422`
- Dispatching a Raven with a `Scroll` object without a `contextName` or `recipient`.
- Attempting to send an Email Notification using a `NotificationContext` that has no `email_template_id` when your email provider or
template source is `sendgrid`.
- Attempting to send an Email Notification using a `NotificationContext` that has no `email_template_filename` when your email
provider is `ses` and template source is `filesystem`.
- Attempting to send a Database Notification using a `NotificationContext` that has no `in_app_template_filename`.
- Attempting to send a Database Notification using a `NotificationContext` that has a non-existent template file that matches the
`in_app_template_filename` in the in-app template directory.
- Attempting to send an Email Notification to a notifiable that has no `email` field or a `routeNotificationForMail()`
method in the model class.

## ⛏️ Built Using
- [PHP](https://www.php.net/) - Language
- [Orchestral Testbench](https://github.com/orchestral/testbench) - Library
- [AWS PHP SDK](https://github.com/aws/aws-sdk-php) - Library
- [Sendgrid PHP Library](https://github.com/sendgrid/sendgrid-php) - Library
- [PHP Mailer](https://github.com/PHPMailer/PHPMailer) - Library

## 📝 TODO
- Add support for SMS notifications

## ✍️ Authors
- [@chijioke-ibekwe](https://github.com/chijioke-ibekwe) - Initial work