Skip to main content
Version: MyBestDealNow

Notification Service

Author(s)

  • Faizal Khan

Last Updated Date

2026-01-13


SRS References


Version History

VersionDateChangesAuthor
1.02026-01-13Initial draft for Notification Service architecture, APIs and featuresFaizal Khan

centralized Notification Platform

Feature Overview

Objective
Implement a centralized notification service that handles all communication with users (Customers and Dealers) across multiple channels. The service acts as a unified gateway for dispatching messages, ensuring consistent communication and centralized management of user preferences.

The service supports four primary delivery channels:

  1. Push Notifications (FCM):
    Real-time alerts sent to mobile devices and web browsers using Firebase Cloud Messaging (FCM). Handles token management and platform-specific payloads (iOS, Android, Web).

  2. In-App Notifications:
    Persistent notifications visible within the application interface. Users can view history, mark items as read, and manage their notification inbox.

  3. Email Notifications:
    Transactional emails (e.g., Welcome, Bid Updates, Reset Password) sent via SMTP. Supports HTML templates and attachments.

  4. SMS Notifications:
    Urgent alerts and verification codes sent directly to user mobile numbers via Twilio.

The service is designed to be event-driven, consuming messages from other services (like Auction Engine, Identity Service) to trigger notifications asynchronously, ensuring high performance and decoupling.


Scope

This Service covers the following features:

  • Device Token Management:

    • Registration of FCM tokens for devices.
    • Automatic handling of token updates and deletions.
  • In-App Notification Center:

    • deeply integrated inbox for users to view past alerts.
    • Read/Unread status tracking.
    • Categorization (Bids, Messages, System, etc.).
  • User Preference Management:

    • Users can toggle specific notification types (e.g., turn off Push for marketing).
  • Multi-Channel Dispatching:

    • unified logic to send a single notification event to multiple channels based on user preference and priority.
  • Real-Time Broadcasting:

    • Integration with SignalR (via Auction Engine) to show notifications instantly while the user is online.

Dependencies

To support this service, the following systems must be integrated:

  • Identity Service (IAM) – To validate users and retrieve contact details (Email, Phone).
  • Auction Engine Service – Major source of events (New Bid, Auction Ended) and handler for SignalR broadcasting.
  • Firebase Cloud Messaging (FCM) – For sending push notifications.
  • Twilio – For sending SMS messages.
  • SMTP Server / Microsoft Graph – For sending emails.
  • Message Bus (RabbitMQ/MassTransit) – For receiving notification triggers from other microservices.

Requirements

Functional Requirements

1. Device Token Lifecycle

  • Mobile and Web clients must register their FCM tokens upon login.
  • Tokens must be associated with the specific logged-in user.
  • System must handle token invalidation and refreshment.
  • Support for multiple devices per user.

2. In-App Notification Management

  • Users must be able to:
    • Fetch a paginated list of notifications.
    • Filter by category (e.g., Bids, System).
    • Mark individual or all notifications as read.
    • Delete notifications to clean up their inbox.
  • Real-time delivery: When an in-app notification is generated, it should be immediately pushed to the client via SignalR if the user is online.

3. Notification Dispatching

  • The system handles a generic NotificationRequest which specifies:
    • Recipient: User details (Email, Phone, Device Tokens).
    • Channels: List of desired channels (Email, SMS, Push).
    • Type: The specific event type (e.g., BidAccepted).
    • Payload: Dynamic data to fill templates.
  • Templates: Email and SMS content must be generated from pre-defined templates to ensure consistency.

4. Event-Driven Architecture

  • The service must act as a consumer for platform events.
  • Example: When a bid is placed in AuctionEngine, a message is published. NotificationService consumes this and triggers the appropriate alerts to the Customer.

Non-Functional Requirements

1. Reliability

  • Notifications (especially transactional ones like OTPs or detailed Bid info) must not be lost.
  • Implementation of retry policies for failed dispatches (e.g., if SMTP is down).

2. Scalability

  • Must handle bursts of notifications (e.g., 1000 dealers notified of a new hot auction simultaneously).
  • Asynchronous processing via message queues prevents blocking the main thread.

3. Latency

  • Push and In-App notifications should be delivered within seconds of the event occurrence.

Data Models

1. Notification Request Models (Internal/Contract)

public record NotificationRequest
{
public required IReadOnlyDictionary<string, string> Data { get; set; }
public required List<DeliveryMethod> DeliveryMethods { get; set; }
public required NotificationType NotificationType { get; set; }
public required UsersComDetails SendTo { get; set; }
public List<Attachment>? Attachments { get; set; }
}

public record UsersComDetails
{
public string? Name { get; set; }
public required string Email { get; set; }
public required string Phone { get; set; }
public List<string>? DeviceToken { get; set; }
}

public enum DeliveryMethod
{
Email = 0,
SMS = 1,
Push = 2
}

public enum NotificationType
{
None = 0,
ResetPassword = 1,
UserWelcome = 2,
NotifyDealersAboutNewAuction = 3,
NewDealerCreate = 4,
BidAccepted = 5,
NewLowestBidPlaced = 6,
AuctionOneDayReminder = 7,
DealerOutbidAlert = 8,
NonLowestBidPlaced = 9,
}

2. Device Token Models

public record RegisterDeviceRequest(
string DeviceId,
string FcmToken,
Platform Platform
);

public record DeviceToken
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
public string DeviceId { get; set; }
public string FcmToken { get; set; }
public Platform Platform { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}

public enum Platform
{
Android,
iOS,
Web
}

3. In-App Notification Models

public record InAppNotificationFilter : CursorPaginationFilter
{
public InAppNotificationCategory? Category { get; init; }
public bool? IsRead { get; init; }
}

public record Notification
{
public Guid NotificationId { get; set; }
public Guid UserId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public InAppNotificationCategory Category { get; set; }
public bool IsRead { get; set; }
public string? ActionName { get; set; }
public string? ActionValue { get; set; }
public string? Image { get; set; }
public DateTime CreatedAt { get; set; }
}

public enum InAppNotificationCategory
{
All = 0,
Bids = 1,
Messages = 2,
Auctions = 3,
Systems = 4
}

API Interfaces

EndpointMethodParametersResponseResponse Status Codes
/device/registerPOSTRegisterDeviceRequestCommonResponse200, 400, 401, 500
/device/{deviceId}DELETEstring deviceIdCommonResponse200, 400, 401, 404, 500
/in-appGETInAppNotificationFilterResponseWithData<object>200, 400, 401, 500
/in-app/mark-as-readPUTMarkAsReadRequestCommonResponse200, 400, 401, 404, 500
/in-app/deleteDELETEDeleteNotificationRequestCommonResponse200, 400, 401, 404, 500
/settingsPUTUpdatePushNotificationRequestCommonResponse200, 400, 401, 404, 500
/settingsGETNoneNotificationSettingsResponse200, 401, 404, 500

API Request & Response Examples

1. Register Device Token

Endpoint: POST /device/register

Request Body:

{
"deviceId": "unique-device-id-123",
"fcmToken": "fcm-registration-token-abc-xyz",
"platform": 2
}

Note: Platform Enum: 0=Android, 1=iOS, 2=Web

Response Body:

{
"status": 0,
"message": "Device token registered successfully"
}

2. Get In-App Notifications

Endpoint: GET /in-app?pageNumber=1&rowsPerPage=10&isRead=false

Response Body:

{
"data": [
{
"notificationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"userId": "3fa85f64-5717-4562-b3fc-2c963f66afa1",
"title": "New Bid Received",
"description": "Dealer XYZ placed a bid of $25,000 on your Camry.",
"category": 1,
"isRead": false,
"ActionName": "OPEN_AUCTION_DETAILS",
"ActionValue": "dad15c4a-9bb0-4bdf-b815-b26061d55de3",
"image": "https://example.com/icon.png",
"createdAt": "2024-09-15T10:30:00Z"
}
],
"totalNumber": 5,
"hasPreviousPage": false,
"hasNextPage": true
}

3. Mark Notification as Read

Endpoint: PUT /in-app/mark-as-read

Request Body:

{
"notificationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"markAll": false
}

Response Body:

{
"status": 0,
"message": "Notification(s) marked as read successfully"
}

Message Consumers (Internal APIs)

The Notification Service subscribes to various MassTransit events to trigger actions.

1. AddInAppNotificationConsumer

Queue/Topic: AddInAppNotificationRequest

Purpose:

  1. Receives a request to create a permanent in-app notification.
  2. Persists the notification to the database.
  3. Broadcasting: Publishes a BroadcastInAppNotificationRequest event. This secondary event is picked up by the AuctionEngineService to push the notification to the user's active session via SignalR.

Message Contract:

public record AddInAppNotificationRequest
{
public Guid UserId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public InAppNotificationCategory Category { get; set; }
public bool IsRead { get; set; } = false;
public string? ActionName { get; set; }
public string? ActionValue { get; set; }
public string? Image { get; set; }
}

2. BatchNotificationConsumer

Queue/Topic: BatchNotificationRequest Purpose: Handles sending notifications to multiple users at once (e.g., notifying all dealers about a new auction matching their inventory).

3. GetNotificationSettingsConsumer

Queue/Topic: GetNotificationSettingsRequest Purpose: Responds to other services enquiring about a user's notification preferences.

3. GetActiveTokensConsumer

Queue/Topic: GetActiveTokensRequest Purpose: Retrieves and sends list of actve tokens for sending push notifications.