VOOZH about

URL: https://deepwiki.com/hypervel/notifications/5.1-mail-channel

⇱ Mail Channel | hypervel/notifications | DeepWiki


Loading...
Menu

Mail Channel

Purpose and Scope

The Mail Channel provides email notification delivery through integration with the hypervel/mail package. It handles both custom Mailable objects and MailMessage instances, orchestrating view rendering, recipient addressing, attachment handling, and message metadata configuration.

This document covers the MailChannel implementation and its integration points. For information about constructing mail message content, see Mail Messages. For details on how channels are selected and invoked, see Core Architecture.


Overview

The MailChannel class serves as the bridge between the notification system and the mail delivery infrastructure. It accepts notification objects, extracts email-specific content via the toMail() method, and coordinates with the MailFactory to send messages.

Key Responsibilities:

  • Invoke notification's toMail() method to obtain message content
  • Determine delivery path (Mailable vs MailMessage)
  • Render views (custom templates or Markdown)
  • Address messages using recipient routing
  • Attach files and raw data
  • Apply priority, tags, and metadata headers
  • Delegate actual mail sending to MailFactory

Sources: src/Channels/MailChannel.php1-251


Channel Architecture

The following diagram illustrates how MailChannel fits into the notification delivery system and its dependencies:


Sources: src/Channels/MailChannel.php24-62


Message Delivery Flow

The send() method implements the primary delivery logic with two distinct paths based on message type:

Dual Path Processing


Path 1: Mailable Objects If toMail() returns a Mailable instance, the channel delegates directly to the mailable's send() method with the MailFactory. This path bypasses all MailChannel-specific processing.

Path 2: MailMessage Objects For MailMessage instances, the channel performs full orchestration:

  1. Verifies recipient routing exists
  2. Builds view content (custom or Markdown)
  3. Merges notification metadata into view data
  4. Constructs message builder closure
  5. Invokes MailFactory::send()

Sources: src/Channels/MailChannel.php38-62


View Rendering

The channel supports two view rendering strategies determined by the presence of a custom view in the MailMessage:

Rendering Strategy Decision

ConditionStrategyMethods
$message->view is setCustom ViewUses specified view template directly
$message->view is nullMarkdown RenderingGenerates HTML and text from Markdown

Markdown Rendering Process


When using Markdown rendering, the channel:

  1. Retrieves the theme from $message->theme or mail.markdown.theme config
  2. Applies theme to the Markdown renderer via theme() method
  3. Renders HTML version with render($message->markdown, $data)
  4. Renders plain text version with renderText($message->markdown, $data)
  5. Returns array with ['html' => ..., 'text' => ...]

Both rendering closures merge the message's data (via $message->data()) with the passed template data.

Sources: src/Channels/MailChannel.php77-122


Recipient Addressing

The channel implements comprehensive recipient addressing including primary recipients, CC, BCC, sender, and reply-to addresses:

Addressing Flow


Primary Recipients Resolution

The getRecipients() method processes the routing result from notifiable->routeNotificationFor('mail', $notification):

Input Formats Accepted:

  • String: Single email address (converted to array)
  • Array of strings: Multiple email addresses
  • Array of objects: Objects with email property
  • Associative array: ['email@example.com' => 'Name']

Processing Logic:

  1. Convert string to array if needed src/Channels/MailChannel.php215-217
  2. Map with keys using mapWithKeys() src/Channels/MailChannel.php219-223
  3. Handle numeric keys (extract email from string or object's email property)
  4. Preserve associative keys (email => name pairs)

CC and BCC Recipients

Both CC and BCC recipients are stored in the MailMessage as arrays of [address, name] tuples:

Sources: src/Channels/MailChannel.php173-224


Message Construction

The buildMessage() method orchestrates the complete message configuration by applying all message properties to the Message instance:

Message Builder Pipeline


Subject Generation

If no explicit subject is set, the channel generates one from the notification class name:

Str::title(Str::snake(class_basename($notification), ' '))

Example: UserRegisteredNotification"User Registered Notification"

Sources: src/Channels/MailChannel.php142-170


Attachments

The channel supports two attachment types via addAttachments():

Attachment Types

TypeStorageMethodParameters
File Attachments$message->attachmentsmailMessage->attach()['file' => path, 'options' => [...]]
Raw Attachments$message->rawAttachmentsmailMessage->attachData()['data' => content, 'name' => filename, 'options' => [...]]

File Attachments: Each attachment in the $message->attachments array contains:

  • file: Path to file on disk
  • options: Array of attachment options (MIME type, as name, etc.)

Raw Attachments: Each attachment in the $message->rawAttachments array contains:

  • data: Raw binary or string data
  • name: Filename to use in the email
  • options: Array of attachment options

Both types are processed iteratively and passed to the underlying Message instance.

Sources: src/Channels/MailChannel.php229-238


Metadata and Headers

The channel applies notification-specific metadata and custom headers to messages:

Additional Message Data

The additionalMessageData() method injects three metadata fields into the view data:


These fields are available in email templates for debugging and tracking purposes.

Tags and Metadata Headers

Tags ($message->tags):

  • Applied as Symfony TagHeader instances
  • Used by email service providers for categorization
  • Each tag added individually via getHeaders()->add(new TagHeader($tag))

Metadata ($message->metadata):

  • Applied as Symfony MetadataHeader instances
  • Key-value pairs for custom email metadata
  • Each pair added as new MetadataHeader($key, $value)

These headers are supported by modern email APIs (SendGrid, Mailgun, etc.) for enhanced tracking and analytics.

Sources: src/Channels/MailChannel.php127-167


Custom Callbacks

The runCallbacks() method executes custom modification closures stored in $message->callbacks:


Each callback receives the underlying Symfony Email instance, allowing direct manipulation of low-level email properties not exposed through the MailMessage API. This provides an escape hatch for advanced customization.

Sources: src/Channels/MailChannel.php243-250


Integration Points

MailFactory Dependency

The MailChannel constructor receives a MailFactory instance from the container:

public function __construct(
 protected MailFactory $mailer,
 protected Markdown $markdown
)

The factory is used to:

  1. Select the appropriate mailer via mailer($message->mailer ?? null)
  2. Execute the send operation with send($view, $data, $builder)
  3. Return a SentMessage instance on successful delivery

Markdown Dependency

The Markdown renderer is injected for Markdown-based notifications:

  • Theme selection via theme($theme) method
  • HTML rendering via render($template, $data)
  • Text rendering via renderText($template, $data)
  • Theme retrieved from $message->theme or mail.markdown.theme config

Configuration Access

The channel accesses configuration through the application container:


Used for retrieving the default Markdown theme when not explicitly set on the message.

Sources: src/Channels/MailChannel.php29-33 src/Channels/MailChannel.php114-122


Error Handling

The channel performs two primary validations:

1. Method Existence Check


Ensures the notification implements the required toMail() method.

2. Recipient Routing Check


For non-Mailable messages, returns null if no mail route is configured on the notifiable. This prevents attempting to send emails without recipient addresses.

Sources: src/Channels/MailChannel.php40-51