Logiche tecniche
Questa sezione descrive come funziona il sistema di notifiche, dalla configurazione dei template all'invio effettivo.
🧠 Concetti chiave
Il sistema di notifiche si basa su un'architettura template-based che separa la configurazione dal codice.
Template di notifica
I template di notifica sono entità configurabili salvate nel database che definiscono:
- Un codice univoco per identificare il template (es.
user_registered,project_completed) - Il titolo e il tipo della notifica (ToDo o Info)
- I canali abilitati (Email, Push)
- Un URL di redirect opzionale dove l'utente viene indirizzato cliccando sulla notifica
Canali di notifica
Ogni template può avere uno o più canali configurati. Ogni canale definisce:
- Il tipo di canale (Email o Push)
- Il titolo specifico per quel canale
- Il corpo del messaggio (con placeholder per variabili)
- I destinatari (lista di indirizzi email o utenti)
- Lo stato (abilitato/disabilitato)
- Per le Email: subject e CTA name (nome del pulsante call-to-action)
Variabili
Le variabili sono placeholder dinamici utilizzabili nei contenuti dei canali con la sintassi {{nome_variabile}}.
Le variabili vengono gestite in modo diverso in base alla loro categoria:
- Variabili CORE: Fornite automaticamente dal sistema (es.
{{platform_name}},{{platform_email}}) - Variabili CONTESTUALI: Fornite dal modulo che invia la notifica in base al contesto (es.
{{user_name}},{{project_address}})
⚙️ Logiche sotto il cofano
Entità coinvolte
Le entità strettamente coinvolte nelle notifiche sono:
-
nt_notification_templates: Template di notifica riutilizzabili. Campi principali:
code: codice univoco per identificare il templatetitle: titolo della notificatype: tipo di notifica (to_do, info)channels: array JSON dei canali abilitatiredirect_url: URL dove reindirizzare l'utente
-
nt_notification_template_channels: Configurazione specifica per ogni canale. Campi principali:
nt_notification_template_id: riferimento al templatetype: tipo di canale (email, push)title: titolo specifico per il canalebody: corpo del messaggio con placeholder variabilirecipients: array JSON di destinatarisubject: oggetto dell'email (solo per Email)cta_name: nome del pulsante CTAstatus: abilitato/disabilitato
-
nt_variable_templates: Variabili disponibili per tutti i template. Campi principali:
name: nome della variabileslug: slug identificativo (usato nei placeholder)category: categoria della variabile (core, project, customer, ecc.)type: tipo di dato (text, email, date, currency, ecc.)
-
nt_notification_variable_template: Tabella pivot che associa variabili ai template
-
notifications: Tabella standard di Laravel che salva le notifiche inviate agli utenti (per il canale Push con driver Database)
-
settings: Impostazioni per utente (es. preferenze di ricezione notifiche)
🔄 Flusso di invio notifica
1. Configurazione iniziale
Prima di poter inviare una notifica, è necessario:
- Creare un template di notifica nel database con un
codeunivoco - Configurare i canali desiderati (Email e/o Push) per quel template
- Associare le variabili necessarie al template
- Creare una classe Notification nel modulo che estende
BaseNotification
2. Invio della notifica
Il modulo Notifiche fornisce un service centralizzato per l'invio. Ci sono diverse modalità:
Modalità 1: Con convenzione (consigliata)
use App\NtModule\Services\NtNotificationService;
use App\YourModule\Notifications\UserRegisteredNotification;
// Il template viene caricato automaticamente dal nome della classe
// UserRegisteredNotification -> cerca il template con code 'user_registered'
NtNotificationService::send(
UserRegisteredNotification::class,
['user_name' => 'Mario Rossi', 'user_email' => 'mario@example.com']
);
// I destinatari vengono risolti automaticamente dai ruoli configurati nel template
Modalità 2: Con template esplicito
// Carica esplicitamente il template
$template = NtNotificationTemplate::where('code', 'user_registered')->first();
NtNotificationService::send(
$template,
UserRegisteredNotification::class,
['user_name' => 'Mario Rossi']
);
Modalità 3: Con contesto (auto-resolve variabili)
// Passa il contesto e le variabili vengono risolte automaticamente
NtNotificationService::send(
UserRegisteredNotification::class,
[],
[],
['user' => $user, 'contract' => $contract]
);
- I destinatari vengono risolti automaticamente dai ruoli configurati nei canali del template
- Le variabili possono essere risolte automaticamente dal contesto (entità passate)
- Il template viene caricato per convenzione dal nome della classe (es.
UserRegisteredNotification→user_registered)
3. Processing interno
Quando viene chiamato NtNotificationService::send(), il sistema:
-
Risolve il template:
- Se passato esplicitamente, lo usa direttamente
- Altrimenti lo carica per convenzione dal nome classe (es.
UserRegisteredNotification→user_registered)
-
Risolve i destinatari:
- Legge i
recipients(ruoli) dai canali abilitati del template - Usa Spatie Permission per trovare tutti gli utenti con quei ruoli
- Raccoglie tutti gli utenti in una collection
- Legge i
-
Risolve le variabili (se passato un contesto):
- Usa
NtVariableResolverper estrarre i valori dalle entità del contesto - Formatta i valori in base al tipo della variabile
- Fa merge con eventuali variabili passate esplicitamente
- Usa
-
Crea l'istanza della notifica:
- Istanzia la classe di notifica passando template, variabili e contesto
- La notifica crea internamente un
NtNotificationServiceper il processing
-
Determina i canali:
- Il metodo
via()della notifica usa il service per mappare i canali - Canali NtModule (Email, Push) → Canali Laravel (mail, database, broadcast)
- Il metodo
-
Prepara i messaggi:
- Per ogni canale, sostituisce i placeholder con i valori delle variabili
toMail(): costruisce il messaggio email usandobuildMailMessage()toArray(): costruisce i dati push usandobuildPushData()toBroadcast(): prepara l'evento per Pusher (se abilitato)
-
Invia:
- Usa
Notification::send($recipients, $notification)di Laravel - Laravel invia la notifica a tutti i destinatari sui canali appropriati
- Usa
📨 Sostituzione delle variabili
Il processo di sostituzione delle variabili supporta due formati di placeholder:
Formato 1: HTML Span (nei contenuti body/title)
Il formato principale usato nei contenuti HTML dei canali:
Ciao <span>@user_name</span>, benvenuto su <span>@platform_name</span>!
Il NtNotificationService cerca il pattern <span>@nome_variabile</span>:
- Estrae il nome della variabile (rimuovendo
@) - Cerca il valore nell'array
$variables - Sostituisce l'intero tag
<span>con il valore
Esempio:
Input: "Ciao <span>@user_name</span>!"
Variables: ['user_name' => 'Mario']
Output: "Ciao Mario!"
Formato 2: Doppie graffe (nei redirect_url)
Usato principalmente negli URL di redirect:
https://example.com/contracts/{{contract_id}}
Il service cerca il pattern {{nome_variabile}} e lo sostituisce con il valore.
Esempio:
Input: "https://example.com/contracts/{{contract_id}}"
Variables: ['contract_id' => '123']
Output: "https://example.com/contracts/123"
Risoluzione automatica dal contesto
Quando si passa un contesto invece di variabili esplicite:
NtNotificationService::send(
NotificationClass::class,
[],
[],
['user' => $user, 'contract' => $contract]
);
Il NtVariableResolver estrae automaticamente i valori:
- Legge le variabili associate al template dal database
- Per ogni variabile, cerca nell'entità corrispondente del contesto
- Estrae il valore usando la configurazione della variabile
- Formatta il valore in base al tipo (date, currency, boolean, ecc.)
- Le variabili CORE devono essere fornite automaticamente dal sistema
- Le variabili CONTESTUALI vengono risolte dal contesto o passate esplicitamente
- In strict mode (
strictMode = true), se una variabile non viene trovata viene lanciata un'eccezione - In modalità normale, i placeholder non sostituiti vengono mantenuti nel testo
- Per le email, il subject viene automaticamente ripulito dai tag HTML
📬 Canali di invio
Email
Per il canale Email:
- Usa la configurazione SMTP di Laravel
- Il mittente viene configurato automaticamente da
BaseNotification - Il subject, body e CTA sono configurabili nel template
- I destinatari sono specificati nel campo
recipientsdel canale
La classe di notifica implementa buildMailMessage() per personalizzare il messaggio:
protected function buildMailMessage($notifiable, array $data)
{
$mail = $this->createMailMessage()
->subject($data['subject'] ?? $data['title'])
->line($data['body']);
if ($data['cta_name'] && $data['redirect_url']) {
$mail->action($data['cta_name'], $data['redirect_url']);
}
return $mail;
}
Push
Per il canale Push il sistema supporta tre modalità (driver):
- Database: Salva la notifica nella tabella
notificationsdi Laravel - Pusher: Invia in real-time tramite Pusher/Broadcasting
- Both: Entrambi i metodi
La classe di notifica implementa buildPushData() per definire i dati:
protected function buildPushData($notifiable, array $data): array
{
return [
'title' => $data['title'],
'body' => $data['body'],
'type' => 'user_registered',
'url' => $data['redirect_url'],
];
}
🎨 Creazione di una nuova notifica
Per creare una nuova notifica:
Step 1: Configurare il template nel database
- Creare un record in
nt_notification_templatescon uncodeunivoco - Creare i record in
nt_notification_template_channelsper ogni canale desiderato - Associare le variabili necessarie tramite
nt_notification_variable_template
Step 2: Creare la classe Notification
namespace App\YourModule\Notifications;
use App\NtModule\Notifications\BaseNotification;
class YourCustomNotification extends BaseNotification
{
protected function getRequiredVariables(): array
{
return ['user_name', 'custom_data'];
}
protected function buildMailMessage($notifiable, array $data)
{
return $this->createMailMessage()
->subject($data['subject'] ?? $data['title'])
->line($data['body'])
->action($data['cta_name'], $data['redirect_url']);
}
protected function buildPushData($notifiable, array $data): array
{
return [
'title' => $data['title'],
'body' => $data['body'],
'type' => 'your_custom_type',
'url' => $data['redirect_url'],
];
}
protected function getBroadcastChannel()
{
return ['private-user.' . $this->notifiable->id];
}
protected function getBroadcastType(): string
{
return 'your.custom.event';
}
}
Step 3: Usare la notifica
use App\NtModule\Services\NtNotificationService;
// Modalità semplice con convenzione (consigliata)
NtNotificationService::send(
YourCustomNotification::class,
[
'user_name' => $user->name,
'custom_data' => 'Some value',
]
);
// Oppure con contesto per auto-resolve
NtNotificationService::send(
YourCustomNotification::class,
[],
[],
['user' => $user, 'project' => $project]
);
// I destinatari vengono risolti automaticamente dai ruoli nel template
🔧 Impostazioni utente
Gli utenti possono configurare le proprie preferenze di notifica tramite la tabella settings:
- Disabilitare completamente le notifiche
- Disabilitare specifici canali (es. solo Email, no Push)
- Disabilitare specifici tipi di notifica
Le impostazioni sono salvate come record polimorfi associati all'utente con una key univoca che identifica il tipo di impostazione.