imagina / inotification
Module handling the real time notifications
Installs: 4
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 6
Forks: 8
Type:asgard-module
Requires
- php: ^8.1
- composer/installers: ~1.0
- imagina/core-module: ^10.0
- kawankoding/laravel-fcm: ^0.2.0
- symfony/http-client: ^6.4
- symfony/mailgun-mailer: ^6.4
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.27.0
- orchestra/testbench: ^8.5
- phpunit/phpunit: ^10
Suggests
- pusher/pusher-php-server: Allows notifications to enable real-time notifications.
README
Improved version of the Asgard Notification Module - https://github.com/AsgardCms/Notification
##Realease Notes
Added
- Rules
CreateNotificationRequest
- Validation message for request rules
Labs Mobile
default provider for SMS notificationsProvider
,Rule
,Template
andTypeNotification
Asgard Entities ScaffolddefaultEmailView
configprovider
andrecipient
columns intonotification__notifications
tablenotificationTypes
config to be seeded in the notification__notification_types tableproviders
config to add new providers configurationsNotificationTypeTableSeeder
depending on the configEventServiceProvider
to listening dynamically all the events defined in the configproviders
NotificationHandler
to handle all the events listened by theEventServiceProvider
Rule->conditions
validationsImaginaNotification
improved version of theAsgardNotification
Note
with the new
ImaginaNotification
service, the columnuser_id
was replaced byrecipient
in the tablenotification__notifications
Installation
Composer
Execute the following command in your terminal:
composer require imagina/asgardcms-inotifications
Note
After installation you'll have to give you the required permissions to get to the blog module pages in the backend.**
Run migrations and seeders
php artisan module:migrate notification --seed
Providers configuration
#####/Config/config.php
Provider Fields
All the fields necessary to configure the provider: api keys, login, user names, passwords.
Each field need to be defined with the dynamic fields
configuration in the basequasar-app. Here a list of the fields required:
Note
Each Provider field can define the route to the public config to replace the keys from ENV file, just add the configRoute value:
// example: broadcasting pusher config route "configRoute" => "broadcasting.connections.pusher.options.encrypted"
this setting is only used at the time of sending a notification, the rest of the application will continue to use the settings from the .env file.
Provider Settings
The settings necessary to customize the fields of the provider for each Rule
Each setting need to be defined with the dynamic fields
configuration in the basequasar-app. Here a list of the settings required:
Note
the required fields of the Provider have more precedence over the Rule Settings.
Publish the configuration
php artisan module:publish-config notification
Usage
There is two ways for use the sending of notifications:
###1 Quickly send notifications to your frontend application.
Inject the Modules\Notification\Services\Inotification
interface where you need it and assign it to a class variable.
// New Service Inotification use Modules\Notification\Services\Inotification; /** * by type, to user->id recipient */ $this->notification->type('broadcast')->to($user->id) ->push( [ "title" => "test notification", "message" => "message notification", "icon_class" => "fas fa-test", "link" => url(''), "setting" => [ "saveInDatabase" => 1 // now, the notifications with type broadcast need to be save in database to really send the notification ] ] ); /** * by mutiple types, to user->id recipient */ $this->notification->type(['broadcast', 'push'])->to($user->id) ->push( [ "title" => "test notification", "message" => "message notification", "icon_class" => "fas fa-test", "link" => url(''), "setting" => [ "saveInDatabase" => 1 // now, the notifications with type broadcast need to be save in database to really send the notification ] ] ); /** * by provider, to user->email recipient */ $this->notification->provider('email')->to($user->email) ->push( [ "title" => "test notification", "message" => "message notification", "icon_class" => "fas fa-test", "link" => url(''), "view" => "email.view" ] ); /** * by mutiple types defined in the to */ $this->notification->to([ "broadcast" => $user->id, "email" => $user->email, ])->push( [ "title" => "test notification", "message" => "message notification", "icon_class" => "fas fa-test", "link" => url(''), "view" => "email.view", "setting" => [ "saveInDatabase" => 1 // now, the notifications with type broadcast need to be save in database to really send the notification ] ] );
2 Using Events and defining the Notifiable config in each module to administrate from the database by the Rules
Notifiable Configuration
First in each module you need to define the Notifiable config, the Notification module will be detect the configuration and will sending to the frontend for the creation of the Rules, each Rule need to be saved in the database for having effect.
Notifiable conditions configuration
The conditions are configured like the dynamic fields of the basequasar-app. however, there are only 3 types of conditions available:
1 recursive
"EMail" => [ "name" => "EMail", 'value' => [ "comparator" => "", "value" => "" ], 'type' => 'recursive', "fields" => [ "operator" => [ "name" => "operator", 'value' => 'any', 'type' => 'select', 'props' => [ 'label' => 'Email', 'options' => [ ['label' => 'Any', 'value' => 'any'], ['label' => 'Contains', 'value' => 'contains'], ['label' => 'Exact Match', 'value' => 'exactMatch'] ] ], ], "value" => [ "name" => "value", 'value' => '', 'type' => 'text', 'props' => [ 'label' => '' ], ], "type" => [ "name" => "type", 'value' => 'comparatorSimple', 'type' => 'hidden', 'props' => [ 'label' => '' ], ] ] ],
2 select with static options
"NinetyMin" => [ "name" => "NinetyMin", 'value' => 'any', 'type' => 'select', 'props' => [ 'label' => 'Ninety Min', 'options' => [ ['label' => 'Any', 'value' => 'any'], ['label' => 'Yes', 'value' => 'Y'], ['label' => 'No', 'value' => 'N'] ] ], ],
3 select with dynamic options
"idSource" => [ "name" => "idSource", 'value' => 'any', 'type' => 'select', 'loadOptions' => [ 'apiRoute' => 'apiRoutes.setup.sources', 'select' => ['label' => 'title', 'id' => 'id'] ], 'options' => [ ['label' => 'Any', 'value' => 'any'], ], 'props' => [ 'label' => 'Source' ], ],
Note
All conditions require the
any
default value, the handle detects it and validates it
##Event Example
namespace Modules\Iteam\Events; class UserWasJoined { public $user; public $team; // this attribute it's required public $entity; /** * Create a new event instance. * * @param $entity * @param array $data */ public function __construct($user,$team) { $this->user = $user; $this->entity = $team; $this->team = $team; } // this method it's required public function notification(){ return [ "title" => "¡Buenas Noticias!, te han aceptado en el equipo: ".$this->team->title, "message" => "Has sido aceptado en el equipo: ".$this->team->title, "icon_class" => "fas fa-glass-cheers", "link" => "link", "view" => "iteam::emails.userJoined.userJoined", "recipients" => [ "email" => [$this->user->email], "broadcast" => [$this->user->id], "push" => [$this->user->id], ], // here you can send all objects and params necessary to the view template "user" => $this->user, "team" => $this->team ]; } }
Notifiable Config Example
'notifiable' => [ [ "title" => "Lead Opportunity", "entityName" => "Modules\\Ilead\\Entities\\LeadOpportunity", "events" => [ [ "title" => "New Lead Opportunity was created", "path" => "Modules\\Ilead\\Events\\LeadOpportunityWasCreated" ] ], "conditions" => [ "EMail" => [ "name" => "EMail", 'value' => [ "comparator" => "", "value" => "" ], 'type' => 'recursive', "fields" => [ "operator" => [ "name" => "operator", 'value' => 'any', 'type' => 'select', 'props' => [ 'label' => 'Email', 'options' => [ ['label' => 'Any', 'value' => 'any'], ['label' => 'Contains', 'value' => 'contains'], ['label' => 'Exact Match', 'value' => 'exactMatch'] ] ], ], "value" => [ "name" => "value", 'value' => '', 'type' => 'text', 'props' => [ 'label' => '' ], ], "type" => [ "name" => "type", 'value' => 'comparatorSimple', 'type' => 'hidden', 'props' => [ 'label' => '' ], ] ] ], "NinetyMin" => [ "name" => "NinetyMin", 'value' => 'any', 'type' => 'select', 'props' => [ 'label' => 'Ninety Min', 'options' => [ ['label' => 'Any', 'value' => 'any'], ['label' => 'Yes', 'value' => 'Y'], ['label' => 'No', 'value' => 'N'] ] ], ], "idSource" => [ "name" => "idSource", 'value' => 'any', 'type' => 'select', 'loadOptions' => [ 'apiRoute' => 'apiRoutes.setup.sources', 'select' => ['label' => 'title', 'id' => 'id'] ], 'options' => [ ['label' => 'Any', 'value' => 'any'], ], 'props' => [ 'label' => 'Source' ], ], "idStore" => [ "name" => "idStore", 'value' => 'any', 'type' => 'select', 'loadOptions' => [ 'apiRoute' => 'apiRoutes.setup.stores', 'select' => ['label' => 'title', 'id' => 'id'] ], 'options' => [ ['label' => 'Any', 'value' => 'any'], ], 'props' => [ 'label' => 'Store' ], ], ], "settings" => [ "email" => [ "recipients" => [ ['label' => 'Customer Email', 'value' => 'EMail'] ] ], "sms" => [ "recipients" => [ ['label' => 'Day Phone', 'value' => 'DayPhone'], ['label' => 'Evening Phone', 'value' => 'EvePhone'], ['label' => 'Cell Phone', 'value' => 'CellPhone'] ] ], "pusher" => [ "recipients" => [ ['label' => 'Rep 1', 'value' => 'repId'], ['label' => 'Rep 2', 'value' => 'repId2'] ] ], "firebase" => [ "recipients" => [ ['label' => 'Rep 1', 'value' => 'repId'], ['label' => 'Rep 2', 'value' => 'repId2'] ] ], ], ], ]
Provider Config Example providers
"pusher" => [// PUSHER PROVIDER "name" => "Pusher", "systemName" => "pusher", "icon" => "far fa-bell", "color" => "#c223ce", "rules" => [ "numeric", "min:1", ], "fields" => [ "id" => [ 'value' => null, ], "pusherAppEncrypted" => [ "name" => "pusherAppEncrypted", 'value' => true, 'type' => 'toggle', "isFakeField" => 'fields', 'props' => [ 'label' => 'Pusher App Encrypted', 'falseValue' => false, 'trueValue' => true ], "configRoute" => "broadcasting.connections.pusher.options.encrypted" ], "pusherAppId" => [ "name" => "pusherAppId", 'value' => '', 'type' => 'input', "isFakeField" => 'fields', 'required' => true, 'props' => [ 'label' => 'Pusher App Id *' ], "configRoute" => "broadcasting.connections.pusher.app_id" ], "pusherAppKey" => [ "name" => "pusherAppKey", 'value' => '', 'type' => 'input', "isFakeField" => 'fields', 'required' => true, 'props' => [ 'label' => 'Pusher App Key *' ], "configRoute" => "broadcasting.connections.pusher.key" ], "pusherAppSecret" => [ "name" => "pusherAppSecret", 'value' => '', 'type' => 'input', "isFakeField" => 'fields', 'required' => true, 'props' => [ 'label' => 'Pusher App Secret *' ], "configRoute" => "broadcasting.connections.pusher.secret" ], "pusherAppCluster" => [ "name" => "pusherAppCluster", 'value' => '', 'type' => 'input', "isFakeField" => 'fields', 'required' => true, 'props' => [ 'label' => 'Pusher App Cluster *' ], "configRoute" => "broadcasting.connections.pusher.options.cluster" ], "status" => [ "name" => "status", 'value' => '0', 'type' => 'select', 'required' => true, 'props' => [ 'label' => 'Status', 'options' => [ ["label" => 'enabled', "value" => '1'], ["label" => 'disabled', "value" => '0'], ], ], ], "default" => [ "name" => "default", 'value' => false, 'type' => 'checkbox', 'props' => [ 'label' => 'Default', ] ], "saveInDatabase" => [ "name" => "saveInDatabase", 'value' => '1', 'type' => 'select', 'required' => true, 'props' => [ 'label' => 'Save in database', 'options' => [ ["label" => 'enabled', "value" => '1'], ["label" => 'disabled', "value" => '0'], ], ], ], "type" => ['value' => 'broadcast'], ], "settings" => [ "recipients" => [ "name" => "recipients", 'value' => '', 'type' => 'input', "isFakeField" => 'settings', 'props' => [ 'label' => 'Recipients', "hint" => "Enter recipient ID - separate entries with commas" ], ], "status" => [ "name" => "status", 'value' => '0', 'type' => 'select', 'required' => true, 'props' => [ 'label' => 'Enable', 'options' => [ ["label" => 'enabled', "value" => '1'], ["label" => 'disabled', "value" => '0'], ], ], ], "saveInDatabase" => [ "name" => "saveInDatabase", 'value' => '1', 'type' => 'select', 'required' => true, 'props' => [ 'label' => 'Save in database', 'options' => [ ["label" => 'enabled', "value" => '1'], ["label" => 'disabled', "value" => '0'], ], ], ], ] ],