81 lines
2.7 KiB
PHP
81 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Addon;
|
|
use Illuminate\Support\Facades\Mail;
|
|
|
|
/**
|
|
* Sends e-mail notifications via the user's SMTP add-on. The SMTP settings live (encrypted) on the
|
|
* addon row; we configure a runtime mailer from them so no .env editing is needed. Each event type
|
|
* is individually toggleable, so the user controls exactly what they get mailed about.
|
|
*/
|
|
class NotificationService
|
|
{
|
|
/** @return array<string,mixed>|null */
|
|
public function config(): ?array
|
|
{
|
|
return Addon::where('key', 'smtp')->where('installed', true)->first()?->config;
|
|
}
|
|
|
|
public function eventEnabled(string $event): bool
|
|
{
|
|
return (bool) data_get($this->config(), "events.{$event}", false);
|
|
}
|
|
|
|
/** Send only if the SMTP add-on is set up AND this event type is enabled. */
|
|
public function notify(string $event, string $subject, string $body): bool
|
|
{
|
|
if (! $this->eventEnabled($event)) {
|
|
return false;
|
|
}
|
|
|
|
return $this->send($subject, $body);
|
|
}
|
|
|
|
/** Send unconditionally (used by the "send test" button). Returns success, never throws. */
|
|
public function send(string $subject, string $body): bool
|
|
{
|
|
$cfg = $this->config();
|
|
if ($cfg === null || blank($cfg['to_email'] ?? null) || blank($cfg['host'] ?? null)) {
|
|
return false;
|
|
}
|
|
|
|
$this->configureMailer($cfg);
|
|
|
|
try {
|
|
Mail::mailer('homeos_smtp')->raw($body, function ($message) use ($cfg) {
|
|
$message->to($cfg['to_email'])
|
|
->subject('[HomeOS] '.$subject)
|
|
->from($cfg['from_email'] ?: 'homeos@localhost', $cfg['from_name'] ?: 'HomeOS');
|
|
});
|
|
} catch (\Throwable $e) {
|
|
// A transient SMTP failure must not abort the caller (a sweep over many devices, an
|
|
// automation run). Log and report failure so the loop keeps going.
|
|
report($e);
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/** @param array<string,mixed> $cfg */
|
|
private function configureMailer(array $cfg): void
|
|
{
|
|
config(['mail.mailers.homeos_smtp' => [
|
|
'transport' => 'smtp',
|
|
'host' => $cfg['host'],
|
|
'port' => (int) ($cfg['port'] ?? 587),
|
|
'encryption' => ($cfg['encryption'] ?? '') ?: null,
|
|
'username' => ($cfg['username'] ?? '') ?: null,
|
|
'password' => ($cfg['password'] ?? '') ?: null,
|
|
'timeout' => 10,
|
|
]]);
|
|
|
|
// MailManager caches the resolved mailer by name; purge it so a long-running worker
|
|
// (Horizon) picks up config changes instead of reusing the first mailer it built.
|
|
Mail::purge('homeos_smtp');
|
|
}
|
|
}
|