feat: add resend as transactional emails
This commit is contained in:
parent
87dd819ae4
commit
2538890b52
@ -20,6 +20,9 @@ class Email extends Component
|
||||
'settings.smtp_timeout' => 'nullable',
|
||||
'settings.smtp_from_address' => 'required|email',
|
||||
'settings.smtp_from_name' => 'required',
|
||||
'settings.resend_enabled' => 'nullable|boolean',
|
||||
'settings.resend_api_key' => 'nullable'
|
||||
|
||||
];
|
||||
protected $validationAttributes = [
|
||||
'settings.smtp_from_address' => 'From Address',
|
||||
@ -30,48 +33,76 @@ class Email extends Component
|
||||
'settings.smtp_encryption' => 'Encryption',
|
||||
'settings.smtp_username' => 'Username',
|
||||
'settings.smtp_password' => 'Password',
|
||||
'settings.smtp_timeout' => 'Timeout',
|
||||
'settings.resend_api_key' => 'Resend API Key'
|
||||
];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->decrypt();
|
||||
$this->emails = auth()->user()->email;
|
||||
}
|
||||
|
||||
private function decrypt()
|
||||
{
|
||||
if (data_get($this->settings, 'smtp_password')) {
|
||||
try {
|
||||
$this->settings->smtp_password = decrypt($this->settings->smtp_password);
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
public function submitFromFields() {
|
||||
try {
|
||||
$this->resetErrorBag();
|
||||
$this->validate([
|
||||
'settings.smtp_from_address' => 'required|email',
|
||||
'settings.smtp_from_name' => 'required',
|
||||
]);
|
||||
$this->settings->save();
|
||||
$this->emit('success', 'Settings saved successfully.');
|
||||
} catch (\Exception $e) {
|
||||
return general_error_handler($e, $this);
|
||||
}
|
||||
}
|
||||
public function instantSaveResend()
|
||||
{
|
||||
try {
|
||||
$this->submitResend();
|
||||
} catch (\Exception $e) {
|
||||
return general_error_handler($e, $this);
|
||||
}
|
||||
}
|
||||
public function submitResend() {
|
||||
try {
|
||||
$this->resetErrorBag();
|
||||
$this->validate([
|
||||
'settings.resend_api_key' => 'required'
|
||||
]);
|
||||
$this->settings->smtp_enabled = false;
|
||||
$this->settings->save();
|
||||
$this->emit('success', 'Settings saved successfully.');
|
||||
} catch (\Exception $e) {
|
||||
$this->settings->resend_enabled = false;
|
||||
return general_error_handler($e, $this);
|
||||
}
|
||||
}
|
||||
|
||||
public function instantSave()
|
||||
{
|
||||
try {
|
||||
$this->submit();
|
||||
$this->emit('success', 'Settings saved successfully.');
|
||||
} catch (\Exception $e) {
|
||||
$this->settings->smtp_enabled = false;
|
||||
$this->validate();
|
||||
return general_error_handler($e, $this);
|
||||
}
|
||||
}
|
||||
|
||||
public function submit()
|
||||
{
|
||||
$this->resetErrorBag();
|
||||
$this->validate();
|
||||
if ($this->settings->smtp_password) {
|
||||
$this->settings->smtp_password = encrypt($this->settings->smtp_password);
|
||||
} else {
|
||||
$this->settings->smtp_password = null;
|
||||
try {
|
||||
$this->resetErrorBag();
|
||||
$this->validate([
|
||||
'settings.smtp_host' => 'required',
|
||||
'settings.smtp_port' => 'required|numeric',
|
||||
'settings.smtp_encryption' => 'nullable',
|
||||
'settings.smtp_username' => 'nullable',
|
||||
'settings.smtp_password' => 'nullable',
|
||||
'settings.smtp_timeout' => 'nullable',
|
||||
]);
|
||||
$this->settings->resend_enabled = false;
|
||||
$this->settings->save();
|
||||
$this->emit('success', 'Settings saved successfully.');
|
||||
} catch (\Exception $e) {
|
||||
return general_error_handler($e, $this);
|
||||
}
|
||||
|
||||
$this->settings->save();
|
||||
$this->emit('success', 'Transaction email settings updated successfully.');
|
||||
$this->decrypt();
|
||||
}
|
||||
|
||||
public function sendTestNotification()
|
||||
|
@ -13,6 +13,7 @@ class InstanceSettings extends Model implements SendsEmail
|
||||
protected $guarded = [];
|
||||
protected $casts = [
|
||||
'resale_license' => 'encrypted',
|
||||
'smtp_password' => 'encrypted',
|
||||
];
|
||||
|
||||
public static function get()
|
||||
|
@ -6,10 +6,10 @@
|
||||
use Illuminate\Mail\Message;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class EmailChannel
|
||||
{
|
||||
private bool $isResend = false;
|
||||
public function send(SendsEmail $notifiable, Notification $notification): void
|
||||
{
|
||||
$this->bootConfigs($notifiable);
|
||||
@ -20,29 +20,52 @@ public function send(SendsEmail $notifiable, Notification $notification): void
|
||||
}
|
||||
|
||||
$mailMessage = $notification->toMail($notifiable);
|
||||
Mail::send(
|
||||
[],
|
||||
[],
|
||||
fn (Message $message) => $message
|
||||
->from(
|
||||
data_get($notifiable, 'smtp_from_address'),
|
||||
data_get($notifiable, 'smtp_from_name'),
|
||||
)
|
||||
->bcc($recepients)
|
||||
->subject($mailMessage->subject)
|
||||
->html((string)$mailMessage->render())
|
||||
);
|
||||
if ($this->isResend) {
|
||||
foreach($recepients as $receipient) {
|
||||
Mail::send(
|
||||
[],
|
||||
[],
|
||||
fn (Message $message) => $message
|
||||
->from(
|
||||
data_get($notifiable, 'smtp_from_address'),
|
||||
data_get($notifiable, 'smtp_from_name'),
|
||||
)
|
||||
->to($receipient)
|
||||
->subject($mailMessage->subject)
|
||||
->html((string)$mailMessage->render())
|
||||
);
|
||||
}
|
||||
|
||||
} else {
|
||||
Mail::send(
|
||||
[],
|
||||
[],
|
||||
fn (Message $message) => $message
|
||||
->from(
|
||||
data_get($notifiable, 'smtp_from_address'),
|
||||
data_get($notifiable, 'smtp_from_name'),
|
||||
)
|
||||
->bcc($recepients)
|
||||
->subject($mailMessage->subject)
|
||||
->html((string)$mailMessage->render())
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function bootConfigs($notifiable): void
|
||||
{
|
||||
$password = data_get($notifiable, 'smtp_password');
|
||||
if ($password) $password = decrypt($password);
|
||||
|
||||
if (Str::contains(data_get($notifiable, 'smtp_host'),'resend.com')) {
|
||||
config()->set('mail.default', 'resend');
|
||||
config()->set('resend.api_key', $password);
|
||||
} else {
|
||||
if (data_get($notifiable, 'resend_enabled')) {
|
||||
$resendAPIKey = data_get($notifiable, 'resend_api_key');
|
||||
if ($resendAPIKey) {
|
||||
$this->isResend = true;
|
||||
config()->set('mail.default', 'resend');
|
||||
config()->set('resend.api_key', $resendAPIKey);
|
||||
}
|
||||
}
|
||||
if (data_get($notifiable, 'smtp_enabled')) {
|
||||
$password = data_get($notifiable, 'smtp_password');
|
||||
if ($password) $password = decrypt($password);
|
||||
config()->set('mail.default', 'smtp');
|
||||
config()->set('mail.mailers.smtp', [
|
||||
"transport" => "smtp",
|
||||
|
@ -17,7 +17,7 @@ public function __construct(
|
||||
public string|null $value = null,
|
||||
public string|null $label = null,
|
||||
public string|null $helper = null,
|
||||
public bool $instantSave = false,
|
||||
public string|bool $instantSave = false,
|
||||
public bool $disabled = false,
|
||||
public string $defaultClass = "toggle toggle-xs toggle-warning rounded disabled:bg-coolgray-200 disabled:opacity-50 placeholder:text-neutral-700"
|
||||
) {
|
||||
|
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('instance_settings', function (Blueprint $table) {
|
||||
$table->boolean('resend_enabled')->default(false);
|
||||
$table->text('resend_api_key')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('instance_settings', function (Blueprint $table) {
|
||||
$table->dropColumn('resend_enabled');
|
||||
$table->dropColumn('resend_api_key');
|
||||
});
|
||||
}
|
||||
};
|
@ -10,40 +10,80 @@
|
||||
<button>close</button>
|
||||
</form>
|
||||
</dialog>
|
||||
<form wire:submit.prevent='submit' class="flex flex-col pb-10">
|
||||
<div class="flex items-center gap-2">
|
||||
<h2>Transactional Emails</h2>
|
||||
<div class="flex items-center gap-2">
|
||||
<h2>Transactional Emails</h2>
|
||||
</div>
|
||||
<div class="pb-4 ">SMTP settings for password resets, invitations, etc.</div>
|
||||
<form wire:submit.prevent='submitFromFields' class="pb-4">
|
||||
<div class="flex flex-col items-end w-full gap-2 xl:flex-row">
|
||||
<x-forms.input required id="settings.smtp_from_name" helper="Name used in emails." label="From Name" />
|
||||
<x-forms.input required id="settings.smtp_from_address" helper="Email address used in emails."
|
||||
label="From Address" />
|
||||
<x-forms.button type="submit">
|
||||
Save
|
||||
</x-forms.button>
|
||||
@if ($settings->smtp_enabled)
|
||||
<x-forms.button onclick="sendTestEmail.showModal()"
|
||||
class="text-white normal-case btn btn-xs no-animation btn-primary">
|
||||
Send Test Email
|
||||
</x-forms.button>
|
||||
@endif
|
||||
</div>
|
||||
<div class="pb-4 ">SMTP settings for password resets, invitations, etc.</div>
|
||||
<div class="w-32 pb-4">
|
||||
<x-forms.checkbox instantSave id="settings.smtp_enabled" label="Enabled" />
|
||||
</div>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col w-full gap-2 xl:flex-row">
|
||||
<x-forms.input required id="settings.smtp_host" placeholder="smtp.mailgun.org" label="Host" />
|
||||
<x-forms.input required id="settings.smtp_port" placeholder="587" label="Port" />
|
||||
<x-forms.input id="settings.smtp_encryption" helper="If SMTP uses SSL, set it to 'tls'."
|
||||
placeholder="tls" label="Encryption" />
|
||||
</div>
|
||||
<div class="flex flex-col w-full gap-2 xl:flex-row">
|
||||
<x-forms.input id="settings.smtp_username" label="SMTP Username" />
|
||||
<x-forms.input id="settings.smtp_password" type="password" label="SMTP Password" />
|
||||
<x-forms.input id="settings.smtp_timeout" helper="Timeout value for sending emails." label="Timeout" />
|
||||
</div>
|
||||
<div class="flex flex-col w-full gap-2 xl:flex-row">
|
||||
<x-forms.input required id="settings.smtp_from_name" helper="Name used in emails." label="From Name" />
|
||||
<x-forms.input required id="settings.smtp_from_address" helper="Email address used in emails."
|
||||
label="From Address" />
|
||||
</div>
|
||||
@if ($settings->resend_enabled || $settings->smtp_enabled)
|
||||
<x-forms.button onclick="sendTestEmail.showModal()"
|
||||
class="text-white normal-case btn btn-xs no-animation btn-primary">
|
||||
Send Test Email
|
||||
</x-forms.button>
|
||||
@endif
|
||||
</div>
|
||||
</form>
|
||||
<div class="flex flex-col gap-4">
|
||||
<details class="border rounded collapse border-coolgray-500 collapse-arrow ">
|
||||
<summary class="text-xl collapse-title">
|
||||
<div>SMTP Server</div>
|
||||
<div class="w-32">
|
||||
<x-forms.checkbox instantSave id="settings.smtp_enabled" label="Enabled" />
|
||||
</div>
|
||||
</summary>
|
||||
<div class="collapse-content">
|
||||
<form wire:submit.prevent='submit' class="flex flex-col">
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col w-full gap-2 xl:flex-row">
|
||||
<x-forms.input required id="settings.smtp_host" placeholder="smtp.mailgun.org"
|
||||
label="Host" />
|
||||
<x-forms.input required id="settings.smtp_port" placeholder="587" label="Port" />
|
||||
<x-forms.input id="settings.smtp_encryption" helper="If SMTP uses SSL, set it to 'tls'."
|
||||
placeholder="tls" label="Encryption" />
|
||||
</div>
|
||||
<div class="flex flex-col w-full gap-2 xl:flex-row">
|
||||
<x-forms.input id="settings.smtp_username" label="SMTP Username" />
|
||||
<x-forms.input id="settings.smtp_password" type="password" label="SMTP Password" />
|
||||
<x-forms.input id="settings.smtp_timeout" helper="Timeout value for sending emails."
|
||||
label="Timeout" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end gap-4 pt-6">
|
||||
<x-forms.button type="submit">
|
||||
Save
|
||||
</x-forms.button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</details>
|
||||
<details class="border rounded collapse border-coolgray-500 collapse-arrow ">
|
||||
<summary class="text-xl collapse-title">
|
||||
<div>Resend</div>
|
||||
<div class="w-32">
|
||||
<x-forms.checkbox instantSave='instantSaveResend' id="settings.resend_enabled" label="Enabled" />
|
||||
</div>
|
||||
</summary>
|
||||
<div class="collapse-content">
|
||||
<form wire:submit.prevent='submitResend' class="flex flex-col">
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col w-full gap-2 xl:flex-row">
|
||||
<x-forms.input type="password" id="settings.resend_api_key" placeholder="API key" label="Host" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end gap-4 pt-6">
|
||||
<x-forms.button type="submit">
|
||||
Save
|
||||
</x-forms.button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user