Skip to content

Channel Guides

This page documents channel-specific behavior and common development notes.

Email

Flow

  1. EmailChannel validates the payload type.
  2. Creates one NotificationRequest.
  3. Creates one NotificationDelivery per To recipient.
  4. Resolves an active email channel config.
  5. Renders the email body.
  6. Creates a provider through EmailProviderFactory.
  7. Sends through SMTP or Azure Graph.

Providers

ProviderEnumNotes
SMTPEmailProviders.SMTPUses MailKit. Optional username/password authentication.
Azure GraphEmailProviders.AzureGraphUses Microsoft Graph client credentials and sends from SenderIdentity.

Template Rendering

If TemplateData is supplied:

  • the service loads {TemplateName}.html or {TemplateName}_ar.html
  • Arabic falls back to English when the Arabic template file does not exist
  • scalar placeholders can be replaced by property name
  • {{#each CollectionName}}...{{/each}} loops are supported for simple collections

If UseSharedLayout is true, the rendered body is inserted into EmailLayoutTemplate.

Best Practices

  • Keep email payload Body HTML-safe.
  • Prefer typed EmailTemplateData for reusable templates.
  • Add both English and Arabic templates when sending bilingual communication.
  • Avoid sending secrets or one-time codes in logs.

SMS

Flow

  1. SmsChannel validates the payload type.
  2. Creates one request and one delivery.
  3. Normalizes PhoneNumber with RegionCode.
  4. Resolves SMS config.
  5. Sends through GenericHttpSmsProvider.

Provider Contract

The current provider posts JSON to the configured SMS BaseUrl:

json
{
  "recipients": "+201000000000",
  "body": "Message text",
  "sender": "Microtec"
}

It sends:

text
Authorization: Bearer <api-token>

Best Practices

  • Always pass a correct ISO-style region code such as EG.
  • Keep SMS content concise.
  • Store sender identity in channel config unless a specific send needs an override.
  • Add provider response parsing before building business logic around SMS-specific provider states.

Push

Flow

  1. PushChannel validates the payload type.
  2. Requires UserIds.
  3. Creates one NotificationRequest per user.
  4. PushMessagingService resolves matching active and valid device tokens.
  5. Resolves FCM provider by ApplicationTarget and PreferredProvider.
  6. Sends multicast through FCM.
  7. Creates one delivery per device token.
  8. Invalid token responses mark device registrations invalid.

Device Resolution

Device tokens are filtered by:

  • UserId
  • IsActive
  • IsTokenValid
  • Platform
  • ApplicationTarget

Registering Tokens

Use IDeviceTokenClient or the proxy route.

csharp
await deviceTokenClient.RegisterAsync(new RegisterDeviceTokenRequest
{
    Token = "<device-token>",
    Platform = PlatformType.Mobile,
    ApplicationTarget = ApplicationTarget.ERP,
    Provider = PushProviders.FCM,
    DeviceModel = "Android"
}, cancellationToken);

For the same user, subdomain, platform, and application target, registering again updates the existing active token row.

Best Practices

  • Register tokens when the app starts and when the push provider refreshes the token.
  • Send to user ids, not raw device tokens, from business services.
  • Set ApplicationTarget accurately so ERP, POS, and Admin Portal credentials remain isolated.
  • Use RouteUrl for client navigation.
  • Treat push as eventually consistent: devices may be offline, expired, or revoked.

WhatsApp

Send Flow

  1. WhatsAppChannel resolves WhatsApp config.
  2. Creates one request and one delivery.
  3. Reads template name from Data["__wa_template_name"].
  4. Finds a local WhatsAppTemplate for the current subdomain.
  5. Requires T2TemplateId and SyncStatus = Approved.
  6. Builds the T2 template text with ordered parameters.
  7. Sends through Msegat/T2.
  8. Schedules status checking when T2 returns a provider message id.

Template Metadata

Prefer the builder:

csharp
var payload = NotificationBuilder.WhatsApp()
    .WithSubdomain("acme")
    .To("+201000000000")
    .WithTemplate(WhatsAppTemplateNames.SalesInvoiceEn)
    .WithTemplateParams(["Customer", "INV-1001"])
    .WithTemplateDocument("https://files.example/invoice.pdf", "invoice.pdf")
    .Build();

Provisioning

WhatsApp provisioning:

  1. validates Msegat credentials
  2. ensures mandatory local templates exist
  3. syncs them to T2
  4. waits for approval
  5. schedules approval checks until complete or timed out

Statuses:

  • NotStarted
  • Queued
  • Running
  • WaitingForApproval
  • Completed
  • Failed

Best Practices

  • Run provisioning after creating or changing Msegat WhatsApp credentials.
  • Do not send WhatsApp templates until provisioning status is Completed.
  • Keep template parameter order stable because T2 parameters are positional.
  • Store entity metadata for traceability when WhatsApp is related to invoices or other business documents.

Notification Center

Notification Center uses persisted request metadata to show notifications to users and admins.

User operations:

  • list all notifications
  • list by channel
  • get unread count
  • mark one or many as read
  • delete one notification

Admin operations:

  • list all notifications with filters
  • view channel-specific details
  • retry failed notifications

Best Practices

  • Populate ModuleName, ModuleNameAr, ServiceName, ServiceNameAr, and NotificationSettingType.
  • For push, set RouteUrl so frontends can navigate from the notification.
  • Do not rely on raw provider payloads for UI display. Use metadata and response DTOs.

Internal Documentation — Microtec