Appearance
Quick Start And Client Integration
Use Microtec.Notifications.Client in application services. It wraps HTTP delivery, queue delivery, tenant headers, resilience policies, fluent payload builders, and optional proxy controllers.
Package References
In a consuming service, reference:
xml
<PackageReference Include="Microtec.Notifications.Client" Version="x.y.z" />
<PackageReference Include="Microtec.Notifications.Contracts" Version="x.y.z" />If the service uses project references in the shared packages repository, reference the package projects instead.
Integration Shape
Register The Client
csharp
using Microtec.Notifications.Client.Extensions;
builder.Services.AddNotificationsClient(builder.Configuration);With overrides:
csharp
builder.Services.AddNotificationsClient(
builder.Configuration,
options =>
{
options.BaseUrl = "https://notification-service.internal";
options.ClientId = "erp";
options.InternalApiKey = "<internal-api-key>";
options.TimeoutSeconds = 30;
});The extension registers:
INotificationsClient- HTTP delivery strategy
- queue delivery strategy
- notification center client
- channel config client
- credentials client
- device token client
- WhatsApp provisioning client
- seed defaults client
- optional controllers from the client package
Queue delivery requires MassTransit IPublishEndpoint to be registered in the consuming application. Microtec services that already use the shared messaging setup normally have this. For an HTTP-only service, verify DI can resolve INotificationsClient after adding the package.
Configuration
json
{
"NotificationsClient": {
"BaseUrl": "https://notification-service.internal",
"ClientId": "erp",
"InternalApiKey": "<internal-api-key>",
"TimeoutSeconds": 30,
"SourceSystem": null,
"Resilience": {
"Retry": {
"MaxRetryAttempts": 3,
"InitialDelaySeconds": 1,
"UseExponentialBackoff": true
},
"CircuitBreaker": {
"FailureThreshold": 5,
"DurationOfBreakSeconds": 30,
"SamplingDurationSeconds": 60
},
"Timeout": {
"TimeoutSeconds": 30
}
}
}
}Actual NotificationsClientOptions properties are:
| Property | Default | Description |
|---|---|---|
BaseUrl | http://localhost:2031 | Base URL of the Notification service. |
ClientId | erp | Calling service identifier. |
InternalApiKey | empty | Internal API key value sent as InternalApiKey. |
TimeoutSeconds | 120 | HTTP client timeout. |
SourceSystem | null | Optional system sender identity. Makes payload Subdomain optional. |
Resilience | default policy options | Polly retry, timeout, and circuit breaker settings. |
Send Email
csharp
using Microtec.Notifications.Client;
using Microtec.Notifications.Client.Builders;
using Microtec.Notifications.Contracts.Enums;
public sealed class InvoiceNotifier(INotificationsClient notifications)
{
public async Task SendInvoiceEmailAsync(
string email,
string subdomain,
CancellationToken ct)
{
var payload = NotificationBuilder.Email()
.WithSubdomain(subdomain)
.Subject("Invoice ready")
.Body("<p>Your invoice is ready.</p>")
.To(email)
.ModuleName("Sales")
.ServiceName("Invoices")
.NotificationSettingType("InvoiceReady")
.Build();
await notifications.SendViaHttpAsync(payload, ct);
}
}Send SMS
csharp
var payload = NotificationBuilder.Sms()
.WithSubdomain("acme")
.To("+201000000000")
.Region("EG")
.Body("Your verification code is 123456")
.Build();
await notifications.SendAsync(payload, DeliveryMode.Http, cancellationToken);Send Push
Push requires one or more UserIds in the payload. The current client implementation also requires a valid current user id from ITenantContextManager when sending a PushPayload.
csharp
var payload = NotificationBuilder.Push()
.WithSubdomain("acme")
.ToUserIds([userId])
.Title("Order approved")
.Body("Your order has been approved.")
.Platform(PlatformType.All)
.ApplicationTarget(ApplicationTarget.ERP)
.RouteUrl("/orders/123")
.Build();
await notifications.SendViaHttpAsync(payload, cancellationToken);Send WhatsApp Template
WhatsApp sends require an approved local WhatsApp template with a T2 template id.
csharp
var payload = NotificationBuilder.WhatsApp()
.WithSubdomain("acme")
.To("+201000000000")
.WithTemplate(WhatsAppTemplateNames.SalesInvoiceEn)
.WithTemplateParams(["Ahmed", "INV-1001"])
.WithEntityId(invoiceId)
.WithNotificationEntityType(NotificationEntityType.SalesInvoice)
.Build();
await notifications.SendViaHttpAsync(payload, cancellationToken);Use Queue Delivery
csharp
await notifications.SendViaQueueAsync(payload, cancellationToken);Queue delivery publishes SendNotificationEvent. It confirms that the message was published, not that the provider accepted the notification.
Choosing Delivery Mode
Tenant Rules
| Scenario | Required context |
|---|---|
| Tenant notification | Set payload.Subdomain, call .WithSubdomain(...), or run inside a tenant context where ITenantContextManager.GetSubdomain() succeeds. |
| Source-system notification | Set payload.SourceSystem or configure NotificationsClient:SourceSystem. |
| Push notification | Provide payload UserIds and ensure the current context exposes a valid current user id. |
| Device token and Notification Center user APIs | Require X-Subdomain and X-User-Id context. |
Optional Proxy Controllers
AddNotificationsClient(...) also adds controllers from the client package to the consuming app. Their default route prefix is api/notifications.
You can change it:
csharp
builder.Services.AddNotificationsClient(
builder.Configuration,
configureOptions: null,
routePrefix: "api/internal/notifications");The obsolete MapNotificationEndpoints() extension should not be used for new code. Controllers are registered by AddNotificationsClient(...).