Skip to content

@memberjunction/notifications

Unified notification engine for MemberJunction that handles in-app, email, and SMS delivery based on notification types and user preferences. This server-side package coordinates between the MJ entity system, template engine, and communication engine to deliver notifications through the appropriate channels.

graph TD
    subgraph notif["@memberjunction/notifications"]
        NE["NotificationEngine\n(Singleton)"]
        TYPES["SendNotificationParams\nNotificationResult\nDeliveryChannels"]
    end

    subgraph entities["MJ Entity System"]
        UNT["UserNotificationTypes"]
        UNP["UserNotificationPreferences"]
        UNN["UserNotifications\n(In-App Records)"]
    end

    subgraph comm["@memberjunction/communication-engine"]
        CE["CommunicationEngine"]
    end

    subgraph templates["@memberjunction/templates"]
        TE["TemplateEngineServer"]
    end

    subgraph providers["Delivery Channels"]
        INAPP["In-App\n(Database Record)"]
        EMAIL["Email\n(via SendGrid)"]
        SMS["SMS\n(via Twilio)"]
    end

    NE -->|reads types| UNT
    NE -->|checks prefs| UNP
    NE -->|creates| UNN
    NE -->|sends via| CE
    CE -->|renders| TE
    UNN --> INAPP
    CE --> EMAIL
    CE --> SMS

    style notif fill:#7c5295,stroke:#563a6b,color:#fff
    style entities fill:#2d6a9f,stroke:#1a4971,color:#fff
    style comm fill:#2d8659,stroke:#1a5c3a,color:#fff
    style templates fill:#b8762f,stroke:#8a5722,color:#fff
    style providers fill:#2d8659,stroke:#1a5c3a,color:#fff
Terminal window
npm install @memberjunction/notifications
import { NotificationEngine } from '@memberjunction/notifications';
import { SendNotificationParams } from '@memberjunction/notifications';
const engine = NotificationEngine.Instance;
await engine.Config(false, contextUser);
const params: SendNotificationParams = {
userId: 'user-uuid',
typeNameOrId: 'Agent Completion',
title: 'Agent Run Finished',
message: 'Your AI agent has completed processing.',
templateData: {
agentName: 'Data Analyzer',
duration: '2m 34s'
},
resourceTypeId: 'resource-type-uuid',
resourceRecordId: 'agent-run-uuid',
resourceConfiguration: { conversationId: 'conv-uuid' }
};
const result = await engine.SendNotification(params, contextUser);
if (result.success) {
console.log('Channels used:', result.deliveryChannels);
// { inApp: true, email: true, sms: false }
}

Override user preferences and type defaults by specifying exact channels:

const result = await engine.SendNotification({
userId: 'user-uuid',
typeNameOrId: 'System Alert',
title: 'Critical Error',
message: 'Database connection lost',
forceDeliveryChannels: {
inApp: true,
email: true,
sms: true
}
}, contextUser);
flowchart TD
    START["SendNotification()"] --> FORCE{"forceDeliveryChannels\nspecified?"}
    FORCE -->|Yes| USE_FORCE["Use forced channels directly"]
    FORCE -->|No| CHECK_PREFS{"User preference\nexists?"}
    CHECK_PREFS -->|Yes| CHECK_ENABLED{"Preference\nenabled?"}
    CHECK_ENABLED -->|No| ALL_OFF["All channels disabled\n(user opted out)"]
    CHECK_ENABLED -->|Yes| CHECK_ALLOW{"Type allows\nuser preference?"}
    CHECK_ALLOW -->|Yes| USE_PREFS["Use user preference\nper-channel settings"]
    CHECK_ALLOW -->|No| USE_DEFAULTS["Use type defaults"]
    CHECK_PREFS -->|No| USE_DEFAULTS

    style START fill:#2d6a9f,stroke:#1a4971,color:#fff
    style USE_FORCE fill:#2d8659,stroke:#1a5c3a,color:#fff
    style USE_PREFS fill:#2d8659,stroke:#1a5c3a,color:#fff
    style USE_DEFAULTS fill:#b8762f,stroke:#8a5722,color:#fff
    style ALL_OFF fill:#7c5295,stroke:#563a6b,color:#fff

The engine resolves delivery channels with this priority:

  1. Force override: If forceDeliveryChannels is set, use it directly
  2. User opt-out: If user preference exists but Enabled is false, all channels are disabled
  3. User preference: If the notification type allows user preferences, use per-channel settings (InAppEnabled, EmailEnabled, SMSEnabled)
  4. Type defaults: Fall back to DefaultInApp, DefaultEmail, DefaultSMS from the notification type
ChannelHow It Works
In-AppCreates a UserNotification entity record in the database. Synchronous, instant.
EmailRenders the notification type’s EmailTemplateID via TemplateEngineServer, then sends through CommunicationEngine using SendGrid. Fire-and-forget (async).
SMSRenders the notification type’s SMSTemplateID via TemplateEngineServer, then sends through CommunicationEngine using Twilio. Fire-and-forget (async).
PropertyTypeRequiredDescription
userIdstringYesTarget user ID
typeNameOrIdstringYesNotification type name or UUID
titlestringYesShort title (in-app display, email subject)
messagestringYesFull notification message
templateDataRecord<string, unknown>NoData for email/SMS template rendering
resourceTypeIdstringNoLink notification to a resource type
resourceRecordIdstringNoLink notification to a specific record
resourceConfigurationobjectNoNavigation context stored as JSON
forceDeliveryChannelsDeliveryChannelsNoOverride channel resolution
PropertyTypeDescription
successbooleanOverall operation success
inAppNotificationIdstringID of created in-app notification
emailSentbooleanWhether email delivery was initiated
smsSentbooleanWhether SMS delivery was initiated
deliveryChannelsDeliveryChannelsResolved channels used
errorsstring[]Error messages if any
interface DeliveryChannels {
inApp: boolean;
email: boolean;
sms: boolean;
}
PackagePurpose
@memberjunction/coreBaseEngine, Metadata, UserInfo, logging
@memberjunction/core-entitiesUserNotification, UserNotificationType entities
@memberjunction/communication-engineCommunicationEngine for email/SMS delivery
@memberjunction/communication-typesMessage class
@memberjunction/templatesTemplateEngineServer for rendering
@memberjunction/sqlserver-dataproviderUserCache for server-side user lookup
Terminal window
npm run build # Compile TypeScript