feat(mail): make notification failures non-fatal
Add App\Support\SafeNotifier that wraps $notifiable->notify() in a Throwable guard with a logged warning, so SMTP outages (the current Gmail 535 errors) no longer propagate as a 500 to the user. Apply to the two hot paths that were still unprotected: CommentController (new comment, reply, like) and RegisteredUserController (super-admin registration alert). User::sendEmailVerificationNotification() is wrapped inline for the same reason. Also add docs/mail-setup.md covering the three delivery options: Gmail app password (quick), Mailgun, Postmark — with the exact .env keys for each. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
1 parent
a1493462f7
commit
1cefc6ad2d
5 files changed
+125
-5
No files matched your search
@@ -0,0 +1,62 @@
|
||||
# Mail setup
|
||||
|
||||
Mail failures are now non-fatal — a down SMTP will log a warning in
|
||||
`data/logs/laravel.log` but will NOT 500 the user. Still, delivery is a
|
||||
feature; here's how to fix the current Gmail 535 auth errors.
|
||||
|
||||
## Option A — Gmail App Password (quickest, free, ~500 sends/day)
|
||||
|
||||
1. On `[email protected]`:
|
||||
- Enable 2-Step Verification (Google Account → Security).
|
||||
- Generate an **App Password** (Security → App passwords → "Mail", "Other: TAKEONE").
|
||||
- Copy the 16-character password Google shows (no spaces).
|
||||
|
||||
2. `.env`:
|
||||
```env
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_HOST=smtp.gmail.com
|
||||
MAIL_PORT=587
|
||||
MAIL_USERNAME=platformtakeone@gmail.com
|
||||
MAIL_PASSWORD=xxxx-xxxx-xxxx-xxxx # the app password, no quotes needed
|
||||
MAIL_ENCRYPTION=tls
|
||||
MAIL_FROM_ADDRESS=platformtakeone@gmail.com
|
||||
MAIL_FROM_NAME="TAKEONE"
|
||||
```
|
||||
|
||||
3. `php artisan config:clear && php artisan queue:restart`
|
||||
|
||||
4. Smoke test:
|
||||
```bash
|
||||
php artisan app:resend-verification --user=<id-of-an-unverified-user>
|
||||
```
|
||||
|
||||
## Option B — Mailgun (recommended for production)
|
||||
|
||||
```env
|
||||
MAIL_MAILER=mailgun
|
||||
MAILGUN_DOMAIN=mg.takeone.bh
|
||||
MAILGUN_SECRET=key-...
|
||||
MAILGUN_ENDPOINT=api.eu.mailgun.net # or api.mailgun.net for US region
|
||||
MAIL_FROM_ADDRESS=no-reply@takeone.bh
|
||||
MAIL_FROM_NAME="TAKEONE"
|
||||
```
|
||||
|
||||
## Option C — Postmark (also fine)
|
||||
|
||||
```env
|
||||
MAIL_MAILER=postmark
|
||||
POSTMARK_TOKEN=...
|
||||
MAIL_FROM_ADDRESS=no-reply@takeone.bh
|
||||
MAIL_FROM_NAME="TAKEONE"
|
||||
```
|
||||
|
||||
## Resend verification to users whose first email failed
|
||||
|
||||
```bash
|
||||
# One specific user
|
||||
php artisan app:resend-verification --user=42
|
||||
|
||||
# Everyone still unverified (dry-run first)
|
||||
php artisan app:resend-verification --all-unverified --dry-run
|
||||
php artisan app:resend-verification --all-unverified
|
||||
```
|
||||
Reference in new issue
Block a user