Installation
composer require creonit/sendpulse-mailer
Add the package to config/mail.php under mailers:
'sendpulse' => [
'transport' => env('MAILER_DSN', 'sendpulse://default'),
],
Environment Configuration
Use one of the supported DSN formats in .env:
# SMTP (legacy)
MAILER_DSN=sendpulse://USERNAME:PASSWORD@default
# SMTP API (recommended)
MAILER_DSN=sendpulse+smtp-api://USER_ID:SECRET@default
# Automation360 Events
MAILER_DSN=sendpulse+events://USER_ID:SECRET@default
First Use Case Send a basic email with SendPulse-specific headers:
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;
public function sendEmail(MailerInterface $mailer)
{
$email = (new Email())
->to('recipient@example.com')
->subject('Test Email')
->text('Hello from SendPulse!');
$mailer->send($email);
}
Standard Email Sending Leverage Symfony Mailer’s fluent API with SendPulse’s transport:
$mailer->send($email)
->then(function () { /* Success */ })
->otherwise(function (Throwable $e) { /* Failure */ });
Dynamic Headers for Automation Attach SendPulse-specific metadata:
$email->getHeaders()
->addTextHeader('X-SendPulse-Event', 'user_signup')
->add(new \Creonit\SendPulseMailer\Header\SendPulseVariableHeader('user_id', $user->id));
Batch Processing
Use Symfony’s MailerInterface with queues (e.g., Symfony Messenger or Laravel Queues):
$mailer->send($email); // Non-blocking if async transport is configured
AppServiceProvider:
public function register()
{
$this->app->bind(MailerInterface::class, function ($app) {
return new Mailer($app->make(SendPulseTransportFactory::class)->createTransport());
});
}
MailerInterface in unit tests:
$mailer = $this->createMock(MailerInterface::class);
$mailer->expects($this->once())->method('send');
DSN Format Sensitivity
+smtp-api) will fail silently or throw cryptic errors.php artisan config:clear after changes.Header Injection Risks
X-SendPulse-Event) must be text-based or use SendPulseVariableHeader.addHeader(); use the package’s header classes.Rate Limits
$mailer = new Mailer($transport, [
'debug' => true,
]);
$transport->getClient()->setHandler(new \GuzzleHttp\HandlerStack([
new \GuzzleHttp\Middleware::tap(function ($request) {
\Log::debug('SendPulse Request', ['request' => $request]);
}),
]));
Custom Headers
Extend SendPulseVariableHeader for complex data:
class CustomSendPulseHeader extends SendPulseVariableHeader
{
public function __construct(string $name, array $data)
{
parent::__construct($name, json_encode($data));
}
}
Transport Factories
Override SendPulseTransportFactory to add middleware or logging:
class CustomSendPulseTransportFactory extends SendPulseTransportFactory
{
protected function createTransport(): TransportInterface
{
$transport = parent::createTransport();
// Add custom middleware
return new HttpTransport($transport->getClient(), $transport->getUri());
}
}
Event Tracking
Use X-SendPulse-Event for automation triggers, but validate event names against SendPulse’s API docs (e.g., user_signup vs USER_SIGNUP).
How can I help you explore Laravel packages today?