Send Broadcast E_Mails

At some point you may need to broadcast an e-mail message to a large number of recipients (eg. leads, vendors, etc.). This page will describe how to easily broadcast to a large number of recipients similar to the Communicate->Broadcast E-Mail menu or sending an e-mail to all subcribers of the mailing list.

Queuing E_Mail Broadcasts

The most simplistic way is to create a new menu and view, then copy the view located at /views/html/admin/communicate/broadcast_email.html and /views/php/admin/communicate/broadcast_email.php to the new view, and modify as necessary.

HTML FIle

To display the necessary for allowing the user to define the e-mail message, use the followin HTML tag:

`

,
:
Message Contents

This will be replaced with the HTML form containgn all necesary fields to define an e-mail message including scheduled date and time. You may also add any additional form fields to the page if a criteria of exactly who will receive the e-mail message can be set, much like the Communicate->Broadcast E-Mail menu. Lastly, you may also optionally want to copy the bottom box allowing the user to first send a test e-mail before scheduling the broadcast.

PHP File

Within the PHP file of the view, you need to pull in the Broadcaster class. Add the following line within the use staements:

use App\Webapp\Notifications\Broadcaster

Next, add a post() method such as:

public function post(View $view, App $app, Broadcaster $broadcaster):void
{

    // Test e-mail
    if ($app->getAction() == 'send_test') {
        $broadcaster->sendTestEmail($app->post('test_email'));
        $view->addCallout("Successfully sent test e-mail to " . $app->post('test_email'));
        return;
    }

        // Define any needed criteria to filter recipients
        $criteria = [];

    // Add to queue
    $broadcaster->queue(SubscriberNotificationController::class, $criteria);

    // Callout
    $view->addCallout('Successfully queued the message to be sent, and it will send within minutes.  If the message does not send, check to ensure the crontab job on your server is correctly added.');
}

The above simply checks if the "Send Test E-Mail" button was clicked, and if so will send a test-email to the user. Otherwise, it will gather any necessary criteria (eg. is user active, group, or anything else), then execute the Broadcaster::queuE() method which accepts the full class name to the appropriate e-mail controller, and an optional array of the criteria.

Notification Controller Methods

There are two additional methods within the e-mail notification contrller that must be modified as necessary, and are explained below.

getBroadcastIterator(int $offset, array $criteria()

Used to retrive the recipients to sent e-mail to. Passes two arguments, the offset or where to start within the result set for times where the broadcasting halts half way through and restarts. Plus an optional condition array, which is any optional criteria that was specified when initially queuing the message.

Must return a ModelIterator which is also returned by the BaseModel::where method of any Apex model class. Below shows an example of the Simple Mailing List package.

public function getBroadcastIterator(int $offset, array $condition = []):?ModelIterator
{

    // GEt SQL
    $where_sql = "is_active = %b AND is_verified = %b ORDER BY created_at";
    if ($offset > 0) {
        $where_sql .= " OFFSET $offset";
    }

    // Execute SQL, and return
    $iterator = Subscriber::where($where_sql, true, true);
    return $iterator;
}

This method simply executes the `where()` method of the `App\SimpleMailingLIst\Models\Subscriber` model, and executes the necessary SQL statement which returns n instance of the `ModelIterator` class.


#### getBroadcastRecipientobject $model)

While sending the e-mails, for each recipient contained within the `ModelIterator` it will call this method passing it the model instance of the recipient and expect an instance of the [EmailQueueRecipient](https://code.apexpl.io/apex/webapp/trunk/docs/classes/models/emailqueuerecipient/__construct.md) class.  For example:

~~~php
public function getBroadcastRecipient(object $model):?EmailQueueRecipient
{

    // Set contact
    $contact = new EmailContact(
        email: $model->email,
        name: $model->getFullName()
    );

    // Return
    $recip = new EmailQueueRecipient(
        contact: $contact,
        user: => null,
        data: ['sub' => $model],
        tracking_id: (string) $model->id
    );
    return $recip;
}

This simply obtains the necessary information on the recipient, allowing the Notifications::getMergeVars() method to be called to gather all necessary information to personalize the e-mail message with.

All Done!

That's it, once the above is in place the administrator may schedule e-mail broadcasts through the menu menu / view, which will be autoatically sent out to all necessary recipients. Upon completion of the broadcast, you will receive an e-mail giving you a summary of the total number of e-mails sent, duration, etc.