cloud: marketing emails
This commit is contained in:
@@ -56,6 +56,7 @@ class Emails extends Command
|
|||||||
$type = select(
|
$type = select(
|
||||||
'Which Email should be sent?',
|
'Which Email should be sent?',
|
||||||
options: [
|
options: [
|
||||||
|
'updates' => 'Send Update Email to all users',
|
||||||
'emails-test' => 'Test',
|
'emails-test' => 'Test',
|
||||||
'application-deployment-success' => 'Application - Deployment Success',
|
'application-deployment-success' => 'Application - Deployment Success',
|
||||||
'application-deployment-failed' => 'Application - Deployment Failed',
|
'application-deployment-failed' => 'Application - Deployment Failed',
|
||||||
@@ -69,7 +70,7 @@ class Emails extends Command
|
|||||||
'realusers-server-lost-connection' => 'REAL - Server Lost Connection',
|
'realusers-server-lost-connection' => 'REAL - Server Lost Connection',
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
$emailsGathered = ['realusers-before-trial','realusers-server-lost-connection'];
|
$emailsGathered = ['realusers-before-trial', 'realusers-server-lost-connection'];
|
||||||
if (!in_array($type, $emailsGathered)) {
|
if (!in_array($type, $emailsGathered)) {
|
||||||
$this->email = text('Email Address to send to');
|
$this->email = text('Email Address to send to');
|
||||||
}
|
}
|
||||||
@@ -78,6 +79,38 @@ class Emails extends Command
|
|||||||
$this->mail = new MailMessage();
|
$this->mail = new MailMessage();
|
||||||
$this->mail->subject("Test Email");
|
$this->mail->subject("Test Email");
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
|
case 'updates':
|
||||||
|
$teams = Team::all();
|
||||||
|
if (!$teams || $teams->isEmpty()) {
|
||||||
|
echo 'No teams found.' . PHP_EOL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$emails = [];
|
||||||
|
foreach ($teams as $team) {
|
||||||
|
foreach ($team->members as $member) {
|
||||||
|
if ($member->email && $member->marketing_emails) {
|
||||||
|
$emails[] = $member->email;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$emails = array_unique($emails);
|
||||||
|
$this->info("Sending to " . count($emails) . " emails.");
|
||||||
|
foreach ($emails as $email) {
|
||||||
|
$this->info($email);
|
||||||
|
}
|
||||||
|
$confirmed = confirm('Are you sure?');
|
||||||
|
if ($confirmed) {
|
||||||
|
foreach ($emails as $email) {
|
||||||
|
$this->mail = new MailMessage();
|
||||||
|
$this->mail->subject('One-click Services, Docker Compose support');
|
||||||
|
$unsubscribeUrl = route('unsubscribe.marketing.emails', [
|
||||||
|
'token' => encrypt($email),
|
||||||
|
]);
|
||||||
|
$this->mail->view('emails.updates',["unsubscribeUrl" => $unsubscribeUrl]);
|
||||||
|
$this->sendEmail($email);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'emails-test':
|
case 'emails-test':
|
||||||
$this->mail = (new Test())->toMail();
|
$this->mail = (new Test())->toMail();
|
||||||
$this->sendEmail();
|
$this->sendEmail();
|
||||||
@@ -141,20 +174,20 @@ class Emails extends Command
|
|||||||
$this->mail = (new BackupSuccess($backup, $db))->toMail();
|
$this->mail = (new BackupSuccess($backup, $db))->toMail();
|
||||||
$this->sendEmail();
|
$this->sendEmail();
|
||||||
break;
|
break;
|
||||||
// case 'invitation-link':
|
// case 'invitation-link':
|
||||||
// $user = User::all()->first();
|
// $user = User::all()->first();
|
||||||
// $invitation = TeamInvitation::whereEmail($user->email)->first();
|
// $invitation = TeamInvitation::whereEmail($user->email)->first();
|
||||||
// if (!$invitation) {
|
// if (!$invitation) {
|
||||||
// $invitation = TeamInvitation::create([
|
// $invitation = TeamInvitation::create([
|
||||||
// 'uuid' => Str::uuid(),
|
// 'uuid' => Str::uuid(),
|
||||||
// 'email' => $user->email,
|
// 'email' => $user->email,
|
||||||
// 'team_id' => 1,
|
// 'team_id' => 1,
|
||||||
// 'link' => 'http://example.com',
|
// 'link' => 'http://example.com',
|
||||||
// ]);
|
// ]);
|
||||||
// }
|
// }
|
||||||
// $this->mail = (new InvitationLink($user))->toMail();
|
// $this->mail = (new InvitationLink($user))->toMail();
|
||||||
// $this->sendEmail();
|
// $this->sendEmail();
|
||||||
// break;
|
// break;
|
||||||
case 'waitlist-invitation-link':
|
case 'waitlist-invitation-link':
|
||||||
$this->mail = new MailMessage();
|
$this->mail = new MailMessage();
|
||||||
$this->mail->view('emails.waitlist-invitation', [
|
$this->mail->view('emails.waitlist-invitation', [
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\EnvironmentVariable;
|
||||||
use App\Models\Project;
|
use App\Models\Project;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use App\Models\Service;
|
use App\Models\Service;
|
||||||
@@ -68,6 +69,7 @@ class ProjectController extends Controller
|
|||||||
if ($type->startsWith('one-click-service-')) {
|
if ($type->startsWith('one-click-service-')) {
|
||||||
$oneClickServiceName = $type->after('one-click-service-')->value();
|
$oneClickServiceName = $type->after('one-click-service-')->value();
|
||||||
$oneClickService = data_get($services, "$oneClickServiceName.compose");
|
$oneClickService = data_get($services, "$oneClickServiceName.compose");
|
||||||
|
$oneClickDotEnvs = collect(data_get($services, "$oneClickServiceName.envs", []));
|
||||||
if ($oneClickService) {
|
if ($oneClickService) {
|
||||||
$service = Service::create([
|
$service = Service::create([
|
||||||
'name' => "$oneClickServiceName-" . Str::random(10),
|
'name' => "$oneClickServiceName-" . Str::random(10),
|
||||||
@@ -75,7 +77,17 @@ class ProjectController extends Controller
|
|||||||
'environment_id' => $environment->id,
|
'environment_id' => $environment->id,
|
||||||
'server_id' => (int) $server_id,
|
'server_id' => (int) $server_id,
|
||||||
]);
|
]);
|
||||||
|
if ($oneClickDotEnvs->count() > 0) {
|
||||||
|
$oneClickDotEnvs->each(function ($value, $key) use ($service) {
|
||||||
|
EnvironmentVariable::create([
|
||||||
|
'key' => $key,
|
||||||
|
'value' => $value,
|
||||||
|
'service_id' => $service->id,
|
||||||
|
'is_build_time' => false,
|
||||||
|
'is_preview' => false,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
}
|
||||||
$service->parse(isNew: true);
|
$service->parse(isNew: true);
|
||||||
|
|
||||||
return redirect()->route('project.service', [
|
return redirect()->route('project.service', [
|
||||||
|
@@ -2,9 +2,6 @@
|
|||||||
|
|
||||||
namespace App\Notifications;
|
namespace App\Notifications;
|
||||||
|
|
||||||
use App\Notifications\Channels\DiscordChannel;
|
|
||||||
use App\Notifications\Channels\EmailChannel;
|
|
||||||
use App\Notifications\Channels\TelegramChannel;
|
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
use Illuminate\Notifications\Messages\MailMessage;
|
use Illuminate\Notifications\Messages\MailMessage;
|
||||||
|
@@ -50,5 +50,8 @@ class RouteServiceProvider extends ServiceProvider
|
|||||||
}
|
}
|
||||||
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
|
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
|
||||||
});
|
});
|
||||||
|
RateLimiter::for('5', function (Request $request) {
|
||||||
|
return Limit::perMinute(5)->by($request->user()?->id ?: $request->ip());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,28 @@
|
|||||||
|
<?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('users', function (Blueprint $table) {
|
||||||
|
$table->boolean('marketing_emails')->default(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('marketing_emails');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@@ -6,9 +6,5 @@
|
|||||||
"uptime-kuma": {
|
"uptime-kuma": {
|
||||||
"documentation": "https://github.com/louislam/uptime-kuma",
|
"documentation": "https://github.com/louislam/uptime-kuma",
|
||||||
"compose": "c2VydmljZXM6CiAgdXB0aW1lLWt1bWE6CiAgICBpbWFnZTogbG91aXNsYW0vdXB0aW1lLWt1bWE6MQogICAgdm9sdW1lczoKICAgICAgLSB1cHRpbWUta3VtYTovYXBwL2RhdGEK"
|
"compose": "c2VydmljZXM6CiAgdXB0aW1lLWt1bWE6CiAgICBpbWFnZTogbG91aXNsYW0vdXB0aW1lLWt1bWE6MQogICAgdm9sdW1lczoKICAgICAgLSB1cHRpbWUta3VtYTovYXBwL2RhdGEK"
|
||||||
},
|
|
||||||
"uptime-kuma-with-database": {
|
|
||||||
"documentation": "https://github.com/louislam/uptime-kuma",
|
|
||||||
"compose": "c2VydmljZXM6CiAgdXB0aW1lLWt1bWE6CiAgICBpbWFnZTogbG91aXNsYW0vdXB0aW1lLWt1bWE6MQogICAgdm9sdW1lczoKICAgICAgLSB1cHRpbWUta3VtYTovYXBwL2RhdGEK"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
5
resources/views/emails/updates.blade.php
Normal file
5
resources/views/emails/updates.blade.php
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<x-emails.layout>
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
If you do not like to receive these emails, you can unsubscribe [here]({{$unsubscribeUrl}}).
|
||||||
|
</x-emails.layout>
|
@@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -16,3 +17,23 @@ use Illuminate\Support\Facades\Route;
|
|||||||
Route::get('/health', function () {
|
Route::get('/health', function () {
|
||||||
return 'OK';
|
return 'OK';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Route::middleware(['throttle:5'])->group(function () {
|
||||||
|
Route::get('/unsubscribe/{token}', function() {
|
||||||
|
try {
|
||||||
|
$token = request()->token;
|
||||||
|
$email = decrypt($token);
|
||||||
|
if (!User::whereEmail($email)->exists()) {
|
||||||
|
return redirect('/');
|
||||||
|
}
|
||||||
|
if (User::whereEmail($email)->first()->marketing_emails === false) {
|
||||||
|
return 'You have already unsubscribed from marketing emails.';
|
||||||
|
}
|
||||||
|
User::whereEmail($email)->update(['marketing_emails' => false]);
|
||||||
|
return 'You have been unsubscribed from marketing emails.';
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return 'Something went wrong. Please try again or contact support.';
|
||||||
|
}
|
||||||
|
|
||||||
|
})->name('unsubscribe.marketing.emails');
|
||||||
|
});
|
||||||
|
Reference in New Issue
Block a user