Laravel SMTP Integration

This guide covers the integration of the Shoutbox SMTP client specifically with Laravel applications.

Installation

  1. Install the package:
composer require shoutboxnet/shoutbox
  1. Add configuration to config/services.php:
'shoutbox' => [
    'key' => env('SHOUTBOX_API_KEY'),
],
  1. Add to .env:
SHOUTBOX_API_KEY=your-api-key-here

Configuration

Mail Configuration

Update config/mail.php to use Shoutbox SMTP:

'mailers' => [
    'shoutbox' => [
        'transport' => 'shoutbox',
        'key' => env('SHOUTBOX_API_KEY'),
    ],
],

'default' => 'shoutbox',

Service Provider Registration

The package’s service provider automatically registers the SMTP transport. If auto-discovery is disabled, add to config/app.php:

'providers' => [
    // ...
    Shoutbox\Laravel\ShoutboxServiceProvider::class,
],

Basic Usage

Using Mail Facade

use Illuminate\Support\Facades\Mail;

class EmailController extends Controller
{
    public function send()
    {
        Mail::to('[email protected]')
            ->send(new WelcomeEmail());
    }
}

Creating Mailable

use Illuminate\Mail\Mailable;

class WelcomeEmail extends Mailable
{
    public function build()
    {
        return $this->view('emails.welcome')
                    ->subject('Welcome to Our Service');
    }
}

Advanced Features

Attachments with Laravel Storage

use Illuminate\Mail\Mailable;
use Illuminate\Support\Facades\Storage;

class DocumentEmail extends Mailable
{
    private $document;

    public function __construct($document)
    {
        $this->document = $document;
    }

    public function build()
    {
        return $this->view('emails.document')
                    ->subject('Your Document')
                    ->attach(Storage::path($this->document));
    }
}

// Usage
Mail::to('[email protected]')
    ->send(new DocumentEmail('documents/report.pdf'));

Queue Integration

class SendEmailJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private $recipient;

    public function __construct($recipient)
    {
        $this->recipient = $recipient;
    }

    public function handle()
    {
        Mail::to($this->recipient)
            ->send(new WelcomeEmail());
    }
}

// Usage
SendEmailJob::dispatch('[email protected]');

Batch Sending

use Illuminate\Support\Facades\Bus;

class EmailController extends Controller
{
    public function sendBatch(array $recipients)
    {
        $jobs = [];
        
        foreach ($recipients as $recipient) {
            $jobs[] = new SendEmailJob($recipient);
        }

        Bus::batch($jobs)
            ->allowFailures()
            ->dispatch();
    }
}

Rate Limiting

use Illuminate\Support\Facades\RateLimiter;

class EmailService
{
    public function sendWithRateLimit($recipient)
    {
        $executed = RateLimiter::attempt(
            'send-email',
            1, // attempts
            function() use ($recipient) {
                Mail::to($recipient)->send(new WelcomeEmail());
            },
            60 // decay seconds
        );

        if (!$executed) {
            throw new \RuntimeException('Rate limit exceeded');
        }
    }
}

Error Handling

Exception Handling

try {
    Mail::to('[email protected]')
        ->send(new WelcomeEmail());
} catch (\Shoutbox\Exceptions\SmtpException $e) {
    Log::error('SMTP error occurred', [
        'code' => $e->getCode(),
        'message' => $e->getMessage()
    ]);
    throw $e;
} catch (\Exception $e) {
    Log::error('Email error occurred', [
        'message' => $e->getMessage()
    ]);
    throw $e;
}

Custom Exception Handler

namespace App\Exceptions;

use Shoutbox\Exceptions\SmtpException;

class Handler extends ExceptionHandler
{
    public function register()
    {
        $this->renderable(function (SmtpException $e) {
            return response()->json([
                'error' => 'Email service error',
                'message' => $e->getMessage()
            ], 500);
        });
    }
}

Testing

Mail Fake

use Illuminate\Support\Facades\Mail;
use Tests\TestCase;

class EmailTest extends TestCase
{
    public function test_sends_welcome_email()
    {
        Mail::fake();

        // Trigger the email
        $this->post('/register', [
            'email' => '[email protected]',
            'name' => 'Test User'
        ]);

        Mail::assertSent(WelcomeEmail::class, function ($mail) {
            return $mail->hasTo('[email protected]');
        });
    }
}

Queue Testing

use Illuminate\Support\Facades\Queue;

class EmailTest extends TestCase
{
    public function test_queues_email_job()
    {
        Queue::fake();

        SendEmailJob::dispatch('[email protected]');

        Queue::assertPushed(SendEmailJob::class, function ($job) {
            return $job->recipient === '[email protected]';
        });
    }
}

Best Practices

  1. Configuration Management

    • Use environment variables
    • Set up per-environment configs
    • Cache configuration in production
  2. Error Handling

    • Implement proper logging
    • Use custom exception handlers
    • Monitor failed jobs
  3. Performance

    • Use queues for bulk sending
    • Implement rate limiting
    • Monitor queue performance
  4. Testing

    • Use Mail::fake()
    • Test error scenarios
    • Verify queue behavior
  5. Security

    • Validate email addresses
    • Sanitize content
    • Protect credentials

Troubleshooting

Common issues and solutions:

  1. Connection Issues

    • Verify API key
    • Check network connectivity
    • Confirm firewall settings
  2. Queue Problems

    • Check queue worker status
    • Monitor failed jobs
    • Verify queue configuration
  3. Rate Limiting

    • Adjust rate limits
    • Implement proper queuing
    • Monitor sending patterns
  4. Attachment Issues

    • Check file permissions
    • Verify file paths
    • Monitor attachment sizes

Support

For additional support:

  • Review error logs
  • Check documentation
  • Contact support team
  • Join developer community