SMS, Push & Real-Time — WhatsApp, FCM, SignalR
Granit.Notifications supports a wide range of delivery channels beyond email. Each channel is registered independently and resolved via Keyed Services. For provider configuration options, see the configuration reference.
Providers
Section titled “Providers”| Provider | Package | Keyed Service key |
|---|---|---|
| Azure Communication Services | Granit.Notifications.AzureCommunicationServices | "AzureCommunicationServices" |
| AWS SNS | Granit.Notifications.AwsSns | "AwsSns" |
| Twilio | Granit.Notifications.Twilio | "Twilio" |
| Brevo | Granit.Notifications.Brevo | "Brevo" |
context.Services.AddGranitNotificationsSms(opts => opts.Provider = "Brevo");Providers
Section titled “Providers”| Provider | Package | Keyed Service key |
|---|---|---|
| Brevo | Granit.Notifications.Brevo | "Brevo" |
| Twilio | Granit.Notifications.Twilio | "Twilio" |
context.Services.AddGranitNotificationsWhatsApp(opts => opts.Provider = "Brevo");Template language
Section titled “Template language”WhatsApp Business templates are pre-approved per language on Meta’s side. The
channel resolves the language per recipient through a cascade:
context.Culture → recipient.PreferredCulture → the
Granit.Localization.PreferredCulture setting (User → Tenant → Global via
ISettingProvider, soft dependency — skipped when Settings is not wired) →
WhatsAppChannelOptions.DefaultLanguage (default "fr").
Mobile Push
Section titled “Mobile Push”Providers
Section titled “Providers”| Provider | Package | Keyed Service key |
|---|---|---|
| Firebase Cloud Messaging (FCM HTTP v1) | Granit.Notifications.GoogleFcm | "GoogleFcm" |
| Azure Notification Hubs | Granit.Notifications.AzureNotificationHubs | "AzureNotificationHubs" |
| AWS SNS Platform Application | Granit.Notifications.AwsSns | "AwsSns" |
context.Services.AddGranitNotificationsMobilePush(opts => opts.Provider = "GoogleFcm");context.Services.AddGranitNotificationsGoogleFcm();FCM authentication uses the OAuth2 bearer flow of the HTTP v1 API: the
configured service account key (Notifications:GoogleFcm:ServiceAccountJson)
mints access tokens with the firebase.messaging scope. Tokens are cached with
a 5-minute refresh margin and minted single-flight; a 401 invalidates the
cache and retries once.
SignalR
Section titled “SignalR”Real-time notifications delivered via SignalR hub with optional Redis backplane for multi-instance deployments.
context.Services.AddGranitNotificationsSignalR( context.Configuration.GetConnectionString("Redis")!);Map the hub in your application:
context.App.MapHub<NotificationHub>("/hubs/notifications");Web Push
Section titled “Web Push”W3C Web Push (VAPID, RFC 8030/8291/8292) — no dependency on FCM or US cloud providers, European sovereignty by design.
context.Services.AddGranitNotificationsPush();SSE (Server-Sent Events)
Section titled “SSE (Server-Sent Events)”Native .NET 10 SSE channel with authentication, per-user connection limits, and bounded message buffers.
context.Services.AddGranitNotificationsSse();The SSE channel requires authentication (.RequireAuthorization() on the route
group) and enforces per-user connection limits to prevent resource exhaustion.
When the limit is reached, the endpoint returns 429 Too Many Requests.
Message buffers use bounded channels with DropOldest policy.
Multi-replica deployments
Section titled “Multi-replica deployments”SSE connections live on a single pod. Add the Redis backplane so a notification published on any replica reaches users connected to the others:
context.Services.AddGranitNotificationsSseRedisBackplane();Granit.Notifications.Sse.StackExchangeRedis reuses the shared
IConnectionMultiplexer (from Granit.Caching.StackExchangeRedis) over a
pub/sub channel. Malformed messages are logged, counted
(granit.notifications.sse.backplane.message_dropped), and skipped — they
never kill the subscriber loop. Running multi-replica without a backplane
logs a one-shot warning outside Development, because delivery would silently
be partial.
Zulip Bot API chat integration for team notifications.
context.Services.AddGranitNotificationsZulip();See also
Section titled “See also”- Channels overview — channel abstraction and registration
- Email channel — sibling channel implementation
- Configuration — provider-specific options (FCM, SignalR, VAPID, Twilio…)
- Endpoints — mobile push token registration, inbox, preferences
- Wolverine integration — durable retry for real-time delivery failures
- Blog: Server-Sent Events in .NET 10 — how the real-time channel uses native SSE support
- Blog: SSE vs SignalR vs WebSockets — picking the right transport for your real-time notifications