There was a strange request recently. I had to maximize the sending emails given per day. Every email after should not be sent. I understand that with the help of this the client can keep email sending budget in control... but come on...
So here are the steps, how I made it:
Add a new block to the EventServiceProvider. We will connect to the MessageSending event:
// app/Providers/EventServiceProvider.php \Illuminate\Mail\Events\MessageSending::class => [ EmailMessageSendingListener::class, ],
Create the `EmailmessageSendingListener.php`, I commented in the code, so I think it will self explanatory.
// inside EmailmessageSendingListener.php // We don't want to typehint the event right now, however we could.
public function handle(object $event) { // KEY CONTAINS CURRENT DATE ALSO $key = date('Y-m-d'); $todaysRecord = DB::table('email_sent_quotas')->where('date', $key)->first(); $count = 0; // CREATE A CACHE KEY FOR THE EMAIL SENT AND INCREMENT IT IF EXISTS if (! $todaysRecord) { DB::table('email_sent_quotas')->insert(['date' => $key, 'count' => 1]); $count = 1; } else { // INCREMENT HERE, SO WE WILL NOW IF THEY ARE EXCEED THE QUOTA AND HOW MUCH DB::table('email_sent_quotas')->where('date', $key)->increment('count', 1); $count = $todaysRecord->count + 1; } // GET THE TRESHOLD FROM THE CONFIG FILE $threshhold = config('interreg-danube.max_emails_per_day'); if ($count > $threshhold) { return false; } }
As you can see, it uses a database table. You can use Redis also. However I don't suggest Cache, becase in case you clear the cache, you will loose this tracked data also.
Now create a new migration and paste the content from here:
/** * Run the migrations. */ public function up(): void { Schema::create('email_sent_quotas', function (Blueprint $table) { $table->id(); $table->date('date')->useCurrent(); $table->unsignedInteger('count')->default(0); }); } /** * Reverse the migrations. */ public function down(): void { Schema::dropIfExists('email_sent_quotas'); }