Notifications overview

What it does

notifications-manager (includes/notifications-manager/) is the single entry point for sending notifications across email, SMS, and push channels. After Phase 2.2, the architecture is:

do_action('mam_notification_send_message', $message)
                │
                ▼
   MAM_Notification_Dispatcher::handle_action()
                │  (batches route through dispatch_batch() → dispatch_one())
   ┌────────────┼────────────┐
   ▼            ▼            ▼
Email        SMS          Push
Sender       Sender       Sender
   │            │            │
wp_mail()    Twilio       APNs / FCM
or queue     or queue     via MAM_PushDispatcher

Channel routing is driven by the mam_notification_list filter — a registry of notification types, each declaring which channels it supports plus per-channel templates.


Public surface

Class Role
MAM_Notification_Dispatcher Single entry point — receives mam_notification_send_message, normalises input, routes per-message
MAM_Notification_Message Input value object (recipient, type, channel hints, replacements)
MAM_Notification_Result Output value object (per-channel status + errors)
MAM_Email_Sender / MAM_Sms_Sender / MAM_Pn_Sender Per-channel senders
mam_message_and_notification_manager Admin UI + custom-notification triggering
mam_notifications_outbox_viewer Admin grid showing recent dispatches
mam_notifications_list Registers the four bundled core notification types

Hooks fired

Hook Type Purpose
mam_notification_send_message Action (+ legacy filter) Primary entry point. Fire to dispatch a notification
mam_notification_send_pn Action Push-only channel hook
mam_update_pn_status Action Vestigial — registered, no fire sites
mam_cron_manager Filter Notification system registers the queue-processor cron
mam_custom_notifications Action Cron-fired hook for scheduled custom notifications
mam_notification_list Filter Notification-type registry — 68+ subscribers register types here
mam_notification_save_notification_type Filter Admin-side type save
mam_notifications_notification_types Filter Type listing for the admin UI
mam_get_phone_data_before_send Filter Subscriber mam_notification_manager::manage_phone_data injects in-app notification list

DB tables (owned)

Table Purpose
wp_mam_notification_history In-app notification delivery log
wp_mam_sms_queue Unified PN + SMS queue, channel flag distinguishes
wp_mam_mail_queue Email queue (owned by mail-cron-manager)
wp_mam_mail_attachments Email attachment storage

All renamed from wp_tsl_* in PR #31; backward-compat aliases via MAM_Migration_Tasks. Frozen contract — do not rename without aliasing migration.


Three-channel routing

MAM_Notification_Dispatcher::dispatch_one() routes per channel:

For each message, look up the type definition in mam_notification_list.

If phone present (in message OR billing_phone usermeta) AND
   (tsl_notification_text_status_{slug} option is on OR type's default_on includes 'sms'):
       MAM_Sms_Sender::send()

If email present (or recipient_id resolves to a user with email) AND
   (tsl_notification_email_status_{slug} option is on OR type's default_on includes 'email'):
       MAM_Email_Sender::send()

If recipient_id present AND
   (tsl_notification_pn_status_{slug} option is on OR type's default_on includes 'push'):
       MAM_Pn_Sender::send()

Per-channel opt-in is per-type. Admins toggle in Mobile App Manager → Notifications → Settings.

⚠️ Naming inconsistency — the dispatcher reads tsl_notification_*_status_* option keys, but REFACTOR_PLAN.md documents that these were renamed to mam_notification_*_status_* in PR #32. The migration framework’s option aliases mean reads to either name return the same value, so behavior is unchanged. Code uses the legacy tsl_* prefix; the framework redirects.


Cron / immediate dispatch

The dispatcher decides per batch:

$use_cron_if_available = count( $messages ) > 10;
$use_global_cron       = get_option( 'mam_notification_use_cron' ) == 1;
$use_cron              = $use_cron_if_available && $use_global_cron;

Threshold: cron only kicks in for batches of >10 AND when mam_notification_use_cron is on. Smaller batches and non-cron sites send immediately.

See Notification queue and cron.


The legacy add_filter registration

mam_notification_send_message is registered both as add_action (modern) AND add_filter (legacy). The dual registration bridges:

  • Modern callersdo_action('mam_notification_send_message', $msg) discards the return.
  • Legacy callersapply_filters('mam_notification_send_message', $msg) reads the handler’s status return.

The add_filter registration is retained as SC #175 deferred — it bridges legacy apply_filters callers in mam-account-manager and customer-site copies of older plugins. Removable once a deprecation cycle confirms no remaining wild callers.


Bundled notification types

Slug Purpose Default channels
mam-user-roles-welcome_email Sent on first user registration (off — admin enables)
mam-user-roles-lost_password Password-reset code email
mam-user-roles-login-with-email Email signup verification code email
mam-push-notification Generic PN — used by sibling plugins as a fallback (off — admin enables)

Plus 60+ types registered by sibling plugins.


Gotchas


  • Plugin: mam-main
  • Notification types registry
  • Notification channels: email, SMS, push
  • Notification queue and cron
  • Notification history and opt-out
  • Notification template replacements
  • Recipe: Register a notification type
  • Hook: mam_notification_send_message
  • Hook: mam_notification_send_pn
  • Hook: mam_notification_list
  • Hook: mam_custom_notifications
  • Frozen public contracts reference

Metadata

Field Value
Article type Plugin Overview
Plugin slug mam-main
Applies to plugin version 2.1.11+
Category Plugin Reference
Audience PHP developer
Last verified 2026-05-02
Was this article helpful?
Contents

    Need Support?

    Can't find the answer you're looking for? Don't worry we're here to help!