Notification channels: email, SMS, push

Summary

The three channels — email, SMS, push — are routed by MAM_Notification_Dispatcher to per-channel sender classes. Each sender owns its channel-specific transport, queueing, and failure handling. Per-channel routing is gated by the notification-type registry’s default_on plus per-type opt-in option keys.


Email — MAM_Email_Sender

Transport: wp_mail() synchronously, or queue → cron.

Queueing decision: count > 10 AND mam_notification_use_cron option enabled → queue. Otherwise immediate.

Storage:

  • Queue: wp_mam_mail_queue
  • Attachments: wp_mam_mail_attachments
  • History: wp_mam_notification_history

Cron processor: mam_cron_mail::mail_cron() — batch of 50, retry up to 3 times.

Opt-out: Reads wp_mam_email_opted_out (per-user) before sending.

Templating: Uses the tsl_notification_subject_<slug> (email + SMS share subject) and tsl_notification_email_text_<slug> option keys with replacement-token substitution.


SMS — MAM_Sms_Sender

Transport: Global $sms->SendSMS() — typically Twilio, but the global is provider-agnostic. The sender appends a STOP-to-opt-out copy automatically.

Queueing decision: Same as email.

Storage:

  • Queue: wp_mam_sms_queue (unified PN + SMS queue, send_text=1 flag)
  • Phone numbers: usermeta billing_phone
  • History: wp_mam_notification_history

Cron processor: Same mam_cron_mail::mail_cron() — batch of 20 PN/SMS sends per tick.

Opt-out: Read from wp_mam_email_opted_out-style table per phone number (in some configs); STOP-keyword opt-out is provider-side (Twilio handles it).

Templating: Uses tsl_notification_subject_<slug> for the message preview and tsl_notification_text_text_<slug> for the full body.

⚠️ $sms is a global. If absent (no SMS provider configured), the sender silently fails. The dispatcher should null-check; it currently doesn’t (tracked).


Push — MAM_Pn_SenderMAM_PushDispatcher

Transport:

MAM_Pn_Sender::send($msg, $type, $use_cron)
        │
        ▼
do_action('mam_notification_send_pn', $msg)
        │
        ▼
mam_push_notification_manager::send_push_notification()  ← legacy bridge
        │
        ▼
MAM_PushDispatcher::dispatch( MAM_PushNotification )
        │
   ┌────┴────┬───────────┐
   ▼         ▼           ▼
APNs       APNs VoIP    FCM v1
HTTP/2

Queueing decision: Same as email/SMS.

Storage:

  • Queue: wp_mam_sms_queue (send_pn=1 flag)
  • Tokens: usermeta keys mam_app_ios_pn_token, mam_app_android_pn_token, mam_ios_voip_token
  • History: wp_mam_notification_history

Cron processor: Shared with SMS.

Retry: None on the PN flow. Failures land in MAM_PushResult->errors.

Templating: Uses tsl_notification_subject_<slug> for the title and tsl_notification_pn_text_<slug> for the body.


Per-channel send-message message shape

do_action( 'mam_notification_send_message', array(
    'message_type' => 'mam-my-plugin-event_name',
    'recipient_id' => 123,           // WP user id
    'email'        => 'override@example.com',  // optional — defaults to user's email
    'phone'        => '+15551234567',          // optional — defaults to billing_phone usermeta
    'replacements' => array(
        'order_id'        => '42',
        'tracking_number' => 'ABC123',
    ),
    'send_now'     => true,                    // bypass cron
    'data'         => array( ... ),            // arbitrary push payload data
) );

The dispatcher resolves message_type to a registry entry, then per-channel decides whether to send.


Channel-specific failure modes

Channel Common failures Where to diagnose
Email SMTP refused, bounced, rate-limited wp_mail_failed action; outbox viewer
SMS Invalid phone, provider quota, opt-out MAM_Sms_Result; provider dashboard
Push BadDeviceToken, Unregistered, MismatchSenderId MAM_PushResult->errors; outbox viewer

The outbox viewer (Mobile App Manager → Notifications → Outbox) shows recent dispatches across all three channels.


Gotchas

  • Removed dead flags. send_text, send_email, send_pn per-message flags were inert — removed in PR #34. Channel routing comes from the type registry.
  • System chat is a special case. message_type = system_chat bypasses notification-list resolution and fires mam_notification_send_pn directly. Used by the chat manager.
  • Email-channel writes to two tables (wp_mam_mail_queue + wp_mam_notification_history). PN/SMS writes only to wp_mam_sms_queue + wp_mam_notification_history.
  • No retry on push. A push that fails once stays failed; the next attempt requires a fresh mam_notification_send_message fire.

  • Notifications overview
  • Notification types registry
  • Notification queue and cron
  • Notification history and opt-out
  • Push notification credentials and tokens
  • Hook: mam_notification_send_message
  • Hook: mam_notification_send_pn

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
Contents

    Need Support?

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