Add email digests
This commit is contained in:
parent
940fa5fda4
commit
a569ac5cc6
6 changed files with 218 additions and 35 deletions
57
app/Console/Commands/SendDigest.php
Normal file
57
app/Console/Commands/SendDigest.php
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use App\Mail\Digest;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
|
|
||||||
|
class SendDigest extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'digest:send {--D|daily} {--W|weekly} {--M|monthly}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Send a digest of recent updates.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
if (!$this->option('daily') && !$this->option('weekly') && !$this->option('monthly')) {
|
||||||
|
$this->error('No schedule specified.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These are seperated because I may want to send multiple types
|
||||||
|
// of digest in a single commend.
|
||||||
|
if ($this->option('daily')) {
|
||||||
|
foreach (config('app.daily_digest_recipients') as $recipient) {
|
||||||
|
Mail::to($recipient)->send(new Digest('daily', config('app.current_trip_id')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->option('weekly')) {
|
||||||
|
foreach (config('app.weekly_digest_recipients') as $recipient) {
|
||||||
|
Mail::to($recipient)->send(new Digest('weekly', config('app.current_trip_id')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->option('monthly')) {
|
||||||
|
foreach (config('app.monthly_digest_recipients') as $recipient) {
|
||||||
|
Mail::to($recipient)->send(new Digest('monthly', config('app.current_trip_id')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
91
app/Mail/Digest.php
Normal file
91
app/Mail/Digest.php
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Mail;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
use App\Http\Controllers\TrackerController;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Mail\Mailable;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class Digest extends Mailable
|
||||||
|
{
|
||||||
|
use Queueable, SerializesModels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of digest (e.g. weekly, monthly, etc.).
|
||||||
|
* TODO: Replace with enum
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $digest_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current trip locations as a JSON object.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $locations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current trip checkins as a JSON object.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $checkins;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new message instance.
|
||||||
|
*
|
||||||
|
* @param string $digest_type
|
||||||
|
* @param string $trip_id
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(string $digest_type, string $trip_id)
|
||||||
|
{
|
||||||
|
$this->digest_type = $digest_type;
|
||||||
|
$trip = (new TrackerController)->get_trip_data($trip_id);
|
||||||
|
|
||||||
|
$cutoffDateTime = new DateTime();
|
||||||
|
switch ($this->digest_type) {
|
||||||
|
case 'daily':
|
||||||
|
$cutoffDateTime->modify('-1 day');
|
||||||
|
break;
|
||||||
|
case 'weekly':
|
||||||
|
$cutoffDateTime->modify('-1 week');
|
||||||
|
break;
|
||||||
|
case 'monthly':
|
||||||
|
$cutoffDateTime->modify('-1 month');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->locations = array_filter(
|
||||||
|
$trip->locations,
|
||||||
|
function($elem) use ($cutoffDateTime) {
|
||||||
|
$elemDateTime = new DateTime($elem->created_at);
|
||||||
|
return $elemDateTime > $cutoffDateTime;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->checkins = array_filter(
|
||||||
|
$trip->checkins,
|
||||||
|
function($elem) use ($cutoffDateTime) {
|
||||||
|
$elemDateTime = new DateTime($elem->created_at);
|
||||||
|
return $elemDateTime > $cutoffDateTime;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the message.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function build()
|
||||||
|
{
|
||||||
|
return $this->view('emails.digest')
|
||||||
|
->subject("track.bengoldsworthy.net ".ucwords($this->digest_type)." Digest");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,34 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Mail;
|
|
||||||
|
|
||||||
use Illuminate\Bus\Queueable;
|
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
||||||
use Illuminate\Mail\Mailable;
|
|
||||||
use Illuminate\Queue\SerializesModels;
|
|
||||||
|
|
||||||
class WeeklyDigest extends Mailable
|
|
||||||
{
|
|
||||||
use Queueable, SerializesModels;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new message instance.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build the message.
|
|
||||||
*
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function build()
|
|
||||||
{
|
|
||||||
return $this->view('emails.weekly-digest')
|
|
||||||
->subject('Weekly Digest');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -72,6 +72,19 @@ return [
|
||||||
|
|
||||||
'past_trip_ids' => explode(',', env('PAST_TRIP_IDS')),
|
'past_trip_ids' => explode(',', env('PAST_TRIP_IDS')),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Digest Mailing Lists
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The the mailing lists for the various digests.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'daily_digest_recipients' => explode(',', env('DAILY_DIGEST_TO')),
|
||||||
|
'weekly_digest_recipients' => explode(',', env('WEEKLY_DIGEST_TO')),
|
||||||
|
'monthly_digest_recipients' => explode(',', env('MONTHLY_DIGEST_TO')),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Application Timezone
|
| Application Timezone
|
||||||
|
|
57
resources/views/emails/digest.blade.php
Normal file
57
resources/views/emails/digest.blade.php
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--dark: #020202;
|
||||||
|
--light: #fffff0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-size: 16px;
|
||||||
|
margin: 1em;
|
||||||
|
color: var(--dark, #020202);
|
||||||
|
background-color: var(--light, #fffff0);
|
||||||
|
background-color: #fffff0;
|
||||||
|
font-family: "Palatino Linotype", "Book Antiqua", Palatino, serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkin {
|
||||||
|
border-top: 1px solid black;
|
||||||
|
padding: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkin__summary {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkin__title {
|
||||||
|
display: inline;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkin__meta {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<h1>track.bengoldsworthy.net {{ ucwords($digest_type) }} Digest</h1>
|
||||||
|
<p><i>Generated: {{ (new DateTime())->format('D jS F Y') }}</i></p>
|
||||||
|
<p>View the tracker <a href="https://track.bengoldsworthy.net">here.</a></p>
|
||||||
|
<hr>
|
||||||
|
<h2>Checkins</h2>
|
||||||
|
<ol>
|
||||||
|
@foreach($checkins as $checkin)
|
||||||
|
<li>
|
||||||
|
<details class="checkin" id="{{ $checkin->id }}">
|
||||||
|
<summary class="checkin__summary">
|
||||||
|
<h3 class="checkin__title">{!! $checkin->title ?? "<i>Untitled</i>" !!}</h3>
|
||||||
|
<p class="checkin__meta">{!! render_date_difference($checkin->date) !!}</p>
|
||||||
|
</summary>
|
||||||
|
@if($checkin->note)
|
||||||
|
{!! $checkin->note !!}
|
||||||
|
@endif
|
||||||
|
@if($checkin->image_url)
|
||||||
|
<img class="popup__image" loading="lazy" src="{{ $checkin->image_url }}">
|
||||||
|
@endif
|
||||||
|
</details>
|
||||||
|
</li>
|
||||||
|
@endforeach
|
||||||
|
</ol>
|
|
@ -1 +0,0 @@
|
||||||
<p>Hello, world</p>
|
|
Loading…
Reference in a new issue