Change email notifications to manual trigger
- Removed automatic email sending on docket entry creation - Added sendNotification() method to DocketEntryController - Added route for manual notification trigger - Added 'Send Notification' button to Show page - Email now only sends when admin explicitly clicks button - Still in testing mode (chris@deafgain.org only)
This commit is contained in:
parent
2f9670caf9
commit
6f66e0987a
4 changed files with 253 additions and 5 deletions
220
DEPLOYMENT_EMAIL_TESTING.md
Normal file
220
DEPLOYMENT_EMAIL_TESTING.md
Normal file
|
|
@ -0,0 +1,220 @@
|
||||||
|
# Email Notification System - Deployment & Testing Guide
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
Email notification system has been implemented for the MAD Lawsuit v2.0 website. When a new docket entry is created via the admin dashboard, an email notification is automatically sent to subscribers.
|
||||||
|
|
||||||
|
## Testing Mode Configuration
|
||||||
|
**IMPORTANT**: The system is currently in TESTING MODE and will ONLY send emails to `chris@deafgain.org`.
|
||||||
|
|
||||||
|
### Testing Mode Details
|
||||||
|
- **Test Recipient**: chris@deafgain.org
|
||||||
|
- **Purpose**: Verify email functionality without spamming all 28 production subscribers
|
||||||
|
- **Location**: `app/Http/Controllers/Admin/DocketEntryController.php` (line ~155)
|
||||||
|
|
||||||
|
### Production Code (Currently Commented Out)
|
||||||
|
```php
|
||||||
|
// Production code (commented out for testing):
|
||||||
|
// $subscribers = Subscription::where('is_active', true)->get();
|
||||||
|
// foreach ($subscribers as $subscriber) {
|
||||||
|
// Mail::to($subscriber->email)->send(
|
||||||
|
// new NewDocketEntryNotification($entry, $subscriber->unsubscribe_token)
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deployment Steps
|
||||||
|
|
||||||
|
### 1. SSH to Production Server
|
||||||
|
```bash
|
||||||
|
ssh chaulmark@10.4.0.205
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Navigate to Project Directory
|
||||||
|
```bash
|
||||||
|
cd ~/websites/v2.mad-lawsuit.org
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Pull Latest Code
|
||||||
|
```bash
|
||||||
|
git pull origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Rebuild Docker Container
|
||||||
|
```bash
|
||||||
|
docker compose down
|
||||||
|
docker compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Verify Container Status
|
||||||
|
```bash
|
||||||
|
docker compose ps
|
||||||
|
docker compose logs -f app
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6. Clear Laravel Caches
|
||||||
|
```bash
|
||||||
|
docker exec mad-lawsuit-v2 php artisan config:clear
|
||||||
|
docker exec mad-lawsuit-v2 php artisan cache:clear
|
||||||
|
docker exec mad-lawsuit-v2 php artisan view:clear
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing the Email System
|
||||||
|
|
||||||
|
### Test Procedure
|
||||||
|
1. **Login to Admin Dashboard**
|
||||||
|
- URL: https://v2.mad-lawsuit.org/admin/login
|
||||||
|
- Username: eliza
|
||||||
|
- Password: AXEoZWk2AMAD0naw
|
||||||
|
|
||||||
|
2. **Create a Test Docket Entry**
|
||||||
|
- Navigate to "Docket Entries" → "Create New Entry"
|
||||||
|
- Fill in the form:
|
||||||
|
- Date: Today's date
|
||||||
|
- Title: "TEST - Email Notification System"
|
||||||
|
- Summary: "This is a test entry to verify email notifications are working correctly."
|
||||||
|
- Notes: (optional)
|
||||||
|
- Click "Create Docket Entry"
|
||||||
|
|
||||||
|
3. **Verify Email Delivery**
|
||||||
|
- Check chris@deafgain.org inbox
|
||||||
|
- Look for email with subject: "New Court Filing: TEST - Email Notification System"
|
||||||
|
- Verify email formatting and content
|
||||||
|
|
||||||
|
4. **Check Logs**
|
||||||
|
```bash
|
||||||
|
docker exec mad-lawsuit-v2 tail -f storage/logs/laravel.log
|
||||||
|
```
|
||||||
|
- Look for log entries:
|
||||||
|
- "Sending email notification for new docket entry"
|
||||||
|
- "Email notification sent successfully"
|
||||||
|
|
||||||
|
### Expected Email Content
|
||||||
|
- **Subject**: New Court Filing: [Entry Title]
|
||||||
|
- **From**: MAD Lawsuit Court Docket <system@deafgain.org>
|
||||||
|
- **To**: chris@deafgain.org
|
||||||
|
- **Content**:
|
||||||
|
- Professional header with case name
|
||||||
|
- Filing date, title, and summary
|
||||||
|
- "View Full Docket" button linking to https://v2.mad-lawsuit.org
|
||||||
|
- Unsubscribe link (placeholder during testing)
|
||||||
|
|
||||||
|
## SMTP Configuration
|
||||||
|
|
||||||
|
### Gmail SMTP Settings (Already Configured in .env)
|
||||||
|
```env
|
||||||
|
MAIL_MAILER=smtp
|
||||||
|
MAIL_HOST=smtp.gmail.com
|
||||||
|
MAIL_PORT=587
|
||||||
|
MAIL_USERNAME=system@deafgain.org
|
||||||
|
MAIL_PASSWORD=ojvlysraxwjriwzy
|
||||||
|
MAIL_ENCRYPTION=tls
|
||||||
|
MAIL_FROM_ADDRESS="system@deafgain.org"
|
||||||
|
MAIL_FROM_NAME="MAD Lawsuit Court Docket"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Gmail App Password
|
||||||
|
- **Email**: system@deafgain.org
|
||||||
|
- **App Password**: ojvlysraxwjriwzy (16-character Google App Password)
|
||||||
|
- **Note**: This is NOT the regular Gmail password
|
||||||
|
|
||||||
|
## Switching to Production Mode
|
||||||
|
|
||||||
|
### When Ready to Send to All Subscribers
|
||||||
|
1. **Edit DocketEntryController.php**
|
||||||
|
```bash
|
||||||
|
# On production server
|
||||||
|
cd ~/websites/v2.mad-lawsuit.org
|
||||||
|
nano app/Http/Controllers/Admin/DocketEntryController.php
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Update sendEmailNotifications Method** (around line 155)
|
||||||
|
- Comment out the testing code:
|
||||||
|
```php
|
||||||
|
// TESTING MODE (comment out when ready for production)
|
||||||
|
// $testEmail = 'chris@deafgain.org';
|
||||||
|
// $testToken = 'test-unsubscribe-token';
|
||||||
|
// Mail::to($testEmail)->send(new NewDocketEntryNotification($entry, $testToken));
|
||||||
|
```
|
||||||
|
|
||||||
|
- Uncomment the production code:
|
||||||
|
```php
|
||||||
|
// Production code:
|
||||||
|
$subscribers = Subscription::where('is_active', true)->get();
|
||||||
|
foreach ($subscribers as $subscriber) {
|
||||||
|
Mail::to($subscriber->email)->send(
|
||||||
|
new NewDocketEntryNotification($entry, $subscriber->unsubscribe_token)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Commit and Deploy**
|
||||||
|
```bash
|
||||||
|
git add app/Http/Controllers/Admin/DocketEntryController.php
|
||||||
|
git commit -m "Switch email notifications to production mode - send to all subscribers"
|
||||||
|
git push origin main
|
||||||
|
|
||||||
|
# On production server
|
||||||
|
git pull origin main
|
||||||
|
docker compose down
|
||||||
|
docker compose up -d --build
|
||||||
|
docker exec mad-lawsuit-v2 php artisan config:clear
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Email Not Received
|
||||||
|
1. **Check Laravel Logs**
|
||||||
|
```bash
|
||||||
|
docker exec mad-lawsuit-v2 tail -100 storage/logs/laravel.log
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Check Gmail SMTP Connection**
|
||||||
|
```bash
|
||||||
|
docker exec mad-lawsuit-v2 php artisan tinker
|
||||||
|
# In tinker:
|
||||||
|
Mail::raw('Test email', function($msg) {
|
||||||
|
$msg->to('chris@deafgain.org')->subject('Test');
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Verify .env Configuration**
|
||||||
|
```bash
|
||||||
|
docker exec mad-lawsuit-v2 php artisan config:show mail
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
- **Authentication Failed**: Verify Gmail App Password is correct
|
||||||
|
- **Connection Timeout**: Check firewall rules for port 587
|
||||||
|
- **SSL/TLS Errors**: Ensure MAIL_ENCRYPTION=tls (not ssl)
|
||||||
|
|
||||||
|
## Files Modified
|
||||||
|
|
||||||
|
### New Files Created
|
||||||
|
1. `app/Mail/NewDocketEntryNotification.php` - Mailable class
|
||||||
|
2. `resources/views/emails/new-docket-entry.blade.php` - HTML email template
|
||||||
|
|
||||||
|
### Modified Files
|
||||||
|
1. `app/Http/Controllers/Admin/DocketEntryController.php` - Added email sending logic
|
||||||
|
2. `.env` - Updated SMTP configuration
|
||||||
|
|
||||||
|
## Current Status
|
||||||
|
- ✅ Email notification system implemented
|
||||||
|
- ✅ Professional HTML email template created
|
||||||
|
- ✅ SMTP configured with Gmail
|
||||||
|
- ✅ Testing mode active (chris@deafgain.org only)
|
||||||
|
- ✅ Code committed and pushed to repository
|
||||||
|
- ⏳ Awaiting deployment to production server
|
||||||
|
- ⏳ Awaiting email functionality testing
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
1. Deploy to production server (10.4.0.205)
|
||||||
|
2. Test email delivery to chris@deafgain.org
|
||||||
|
3. Verify email formatting and content
|
||||||
|
4. Once confirmed working, switch to production mode
|
||||||
|
5. Update documentation with test results
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Last Updated**: December 18, 2025 at 10:21 AM MST
|
||||||
|
**Status**: Ready for deployment and testing
|
||||||
|
**Git Commit**: 9687b9b9
|
||||||
|
|
@ -63,12 +63,8 @@ class DocketEntryController extends Controller
|
||||||
|
|
||||||
$entry = DocketEntry::create($validated);
|
$entry = DocketEntry::create($validated);
|
||||||
|
|
||||||
// Send email notifications to active subscribers
|
|
||||||
// TESTING MODE: Only send to chris@deafgain.org
|
|
||||||
$this->sendEmailNotifications($entry);
|
|
||||||
|
|
||||||
return redirect()->route('admin.docket-entries.show', $entry->id)
|
return redirect()->route('admin.docket-entries.show', $entry->id)
|
||||||
->with('success', 'Docket entry created successfully. Email notifications sent.');
|
->with('success', 'Docket entry created successfully.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -142,6 +138,17 @@ class DocketEntryController extends Controller
|
||||||
->with('success', 'Docket entry deleted successfully.');
|
->with('success', 'Docket entry deleted successfully.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send email notification to subscribers for this docket entry.
|
||||||
|
*/
|
||||||
|
public function sendNotification(DocketEntry $docketEntry): RedirectResponse
|
||||||
|
{
|
||||||
|
$this->sendEmailNotifications($docketEntry);
|
||||||
|
|
||||||
|
return redirect()->route('admin.docket-entries.show', $docketEntry->id)
|
||||||
|
->with('success', 'Email notifications sent successfully to subscribers.');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send email notifications to subscribers.
|
* Send email notifications to subscribers.
|
||||||
* TESTING MODE: Only sends to chris@deafgain.org
|
* TESTING MODE: Only sends to chris@deafgain.org
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,12 @@ const deleteEntry = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const sendNotification = () => {
|
||||||
|
if (confirm('Send email notification to all subscribers about this docket entry?')) {
|
||||||
|
router.post(route('admin.docket-entries.send-notification', props.entry.id));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const formatFileSize = (bytes: number): string => {
|
const formatFileSize = (bytes: number): string => {
|
||||||
if (bytes < 1024) return bytes + ' B';
|
if (bytes < 1024) return bytes + ' B';
|
||||||
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
|
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
|
||||||
|
|
@ -229,6 +235,20 @@ const formatFileSize = (bytes: number): string => {
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Send Notification -->
|
||||||
|
<div class="bg-blue-50 border border-blue-200 rounded-lg p-6">
|
||||||
|
<h2 class="text-lg font-bold text-blue-900 mb-2">Email Notification</h2>
|
||||||
|
<p class="text-sm text-blue-700 mb-4">
|
||||||
|
Send email notification to all active subscribers about this docket entry.
|
||||||
|
</p>
|
||||||
|
<PrimaryButton
|
||||||
|
@click="sendNotification"
|
||||||
|
class="w-full justify-center bg-blue-600 hover:bg-blue-700"
|
||||||
|
>
|
||||||
|
Send Notification
|
||||||
|
</PrimaryButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Danger Zone -->
|
<!-- Danger Zone -->
|
||||||
<div class="bg-red-50 border border-red-200 rounded-lg p-6">
|
<div class="bg-red-50 border border-red-200 rounded-lg p-6">
|
||||||
<h2 class="text-lg font-bold text-red-900 mb-2">Danger Zone</h2>
|
<h2 class="text-lg font-bold text-red-900 mb-2">Danger Zone</h2>
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ Route::prefix('admin')->name('admin.')->group(function () {
|
||||||
|
|
||||||
// Docket entry routes
|
// Docket entry routes
|
||||||
Route::resource('docket-entries', \App\Http\Controllers\Admin\DocketEntryController::class);
|
Route::resource('docket-entries', \App\Http\Controllers\Admin\DocketEntryController::class);
|
||||||
|
Route::post('/docket-entries/{docketEntry}/send-notification', [\App\Http\Controllers\Admin\DocketEntryController::class, 'sendNotification'])->name('docket-entries.send-notification');
|
||||||
|
|
||||||
// Document routes
|
// Document routes
|
||||||
Route::post('/docket-entries/{docketEntry}/documents', [\App\Http\Controllers\Admin\DocumentController::class, 'store'])->name('documents.store');
|
Route::post('/docket-entries/{docketEntry}/documents', [\App\Http\Controllers\Admin\DocumentController::class, 'store'])->name('documents.store');
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue