Infrastruktur: Shared Hosting (Hostinger/Qwords)
Framework: Laravel 8, 9, 10, atau 11
Tujuan: Mencegah blokir SMTP dengan kebijakan Zero Bounce.
BAGIAN 1: Fondasi Infrastruktur (Wajib)
Sebelum menulis kode Laravel, Anda harus memastikan domain Anda memiliki "Surat Izin Mengemudi" di internet. Tanpa ini, validasi Laravel tidak ada gunanya karena email tetap akan ditolak.
Langkah Konfigurasi di Panel Hosting:
- Masuk ke hPanel (Hostinger) atau cPanel (Qwords).
- Cari menu Email Deliverability atau DNS Zone Editor.
- Pastikan dua record ini aktif:
- SPF (Sender Policy Framework): Mengizinkan IP hosting mengirim email.
- DKIM (DomainKeys Identified Mail): Menandatangani email agar tidak dianggap palsu.
Peringatan: Jika status SPF/DKIM belum "Active/Valid" (berwarna hijau), jangan lanjutkan ke tahap coding. Hubungi CS Hosting Anda jika bingung cara mengaktifkannya.
BAGIAN 2: Validasi Tingkat Lanjut (The Gatekeeper)
Di Laravel, kita tidak validasi di Controller, melainkan menggunakan Form Request agar kode bersih dan reusable. Kita akan menggunakan fitur validasi DNS bawaan Laravel.
1. Buat Request Validation
Jalankan perintah terminal:
php artisan make:request StoreUserRequest
2. Terapkan Aturan Ketat
Buka file app/Http/Requests/StoreUserRequest.php dan ubah menjadi seperti ini:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class StoreUserRequest extends FormRequest
{
public function authorize()
{
return true; // Pastikan true agar bisa dipakai
}
public function rules()
{
return [
'email' => [
'required',
'string',
// -------------------------------------------------------
// LAPIS 1: Syntax Check
// 'rfc' memeriksa kesesuaian format standar internet (RFC)
// -------------------------------------------------------
// LAPIS 2: DNS Check (Paling Penting)
// 'dns' melakukan ping ke domain penerima (MX Record).
// Jika domain mati/palsu, validasi ini akan GAGAL.
// -------------------------------------------------------
'email:rfc,dns',
// LAPIS 3: Blacklist Manual (Untuk bot/spam user umum)
'not_in:test@gmail.com,admin@gmail.com,user@example.com,root@localhost',
// LAPIS 4: Database Check (Agar tidak duplikat)
'unique:users,email',
],
// Validasi input lainnya (misal file upload)
'file' => 'required|file|max:2048',
];
}
public function messages()
{
return [
'email.required' => 'Email wajib diisi.',
'email.email' => 'Format email tidak valid.',
// Pesan ini muncul jika domain penerima mati/tidak ada
'email.dns' => 'Domain email tidak ditemukan atau tidak aktif. Mohon gunakan email asli.',
'email.not_in' => 'Alamat email sistem/testing tidak diizinkan.',
'email.unique' => 'Email ini sudah terdaftar.',
];
}
}
3. Opsi Tambahan: Anti-Disposable Email (Opsional)
Jika Anda ingin memblokir email sementara (seperti yopmail), Anda bisa menginstal package tambahan. Namun, jika ingin tanpa package (hemat resource), Anda bisa membuat Custom Rule.
Buat Rule:
php artisan make:rule DisposableEmail
Edit app/Rules/DisposableEmail.php:
public function passes($attribute, $value)
{
$domain = substr(strrchr($value, "@"), 1);
// Daftar domain sampah (Anda bisa update manual atau ambil dari API/Json)
$blockedDomains = ['yopmail.com', 'mailinator.com', '10minutemail.com', 'tempmail.com'];
return !in_array(strtolower($domain), $blockedDomains);
}
public function message()
{
return 'Email sementara (disposable) tidak diizinkan.';
}
Pasang di Request tadi:
use App\Rules\DisposableEmail;
'email' => ['required', 'email:rfc,dns', new DisposableEmail],
BAGIAN 3: Implementasi di Controller
Sekarang controller Anda bersih. Jika kode masuk ke dalam method controller, berarti email DIJAMIN valid, aktif, dan bukan spam.
use App\Http\Requests\StoreUserRequest;
use App\Models\User;
use Illuminate\Support\Facades\Mail;
use App\Mail\WelcomeEmail;
public function register(StoreUserRequest $request)
{
// 1. Upload File (Aman, karena email sudah valid)
$path = $request->file('file')->store('uploads');
// 2. Simpan User
$user = User::create([
'email' => $request->email,
// ...
]);
// 3. Kirim Email Menggunakan QUEUE (Wajib untuk Shared Hosting)
// Jangan pakai send(), pakai queue()
Mail::to($user->email)->queue(new WelcomeEmail($user));
return response()->json(['message' => 'Registrasi sukses! Cek email Anda.']);
}
BAGIAN 4: Mengatur Antrean (Queue) di Shared Hosting
Shared hosting memiliki batas waktu eksekusi (timeout) dan batas pengiriman email per jam. Mengirim email secara langsung (send()) akan membuat loading lama dan berisiko error.
1. Ubah Driver Queue
Edit file .env:
QUEUE_CONNECTION=database
2. Siapkan Tabel Queue
Jalankan di terminal (lokal atau SSH hosting):
php artisan queue:table
php artisan migrate
3. Setup Worker di Shared Hosting (CRON JOB)
Karena di shared hosting Anda biasanya tidak bisa menjalankan supervisor, kita gunakan Cron Job.
- Masuk ke panel hosting, cari menu Cron Jobs.
- Buat Cron Job baru yang berjalan Setiap Menit (
* * * * *). - Masukkan perintah (sesuaikan path dengan hosting Anda):
/usr/bin/php /home/username_hosting/public_html/artisan queue:work --stop-when-empty --tries=3 --timeout=90
Penjelasan Command:
-
--stop-when-empty: Worker akan berhenti jika tidak ada email antre (hemat RAM hosting). -
--tries=3: Jika gagal kirim, coba ulang 3 kali sebelum menyerah. -
--timeout=90: Batas waktu proses.
BAGIAN 5: Tips Keamanan Tambahan (Rate Limiting)
Untuk menghindari blokir dari Hostinger karena mengirim terlalu cepat, tambahkan jeda pada Mailable Anda.
Buka file Mail Anda (contoh: app/Mail/WelcomeEmail.php), tambahkan implementasi ShouldQueue dan properti delay:
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
// Pastikan implement ShouldQueue
class WelcomeEmail extends Mailable implements ShouldQueue
{
use Queueable, SerializesModels;
public function build()
{
return $this->view('emails.welcome')
->subject('Selamat Datang!');
}
}
Trik Delay saat mengirim:
Jika Anda melakukan blasting (kirim ke banyak orang sekaligus), beri jeda manual:
$users = User::all();
foreach ($users as $index => $user) {
// Kirim email setiap 10 detik agar Hostinger tidak marah
$delay = now()->addSeconds($index * 10);
Mail::to($user)->later($delay, new WelcomeEmail($user));
}
RINGKASAN (Checklist)
- ✅ DNS: SPF & DKIM Hostinger sudah aktif.
- ✅ Validasi: Menggunakan
email:rfc,dnsdi FormRequest. - ✅ Queue: Menggunakan database queue, bukan
sync. - ✅ Cron Job: Cron job aktif untuk memproses queue di background.
- ✅ Testing: Sudah mencoba kirim ke email sendiri dan TIDAK mencoba ke
test@gmail.com.
Dokumentasi ini sudah siap Anda gunakan sebagai pedoman standar (SOP) untuk tim development Anda.
Top comments (1)
Terima kasih sudah membahas topik niche soal email Laravel di shared hosting—jarang ada yang sedetail ini.