Installation:
composer require crs/sendgrid-symfony:~1.0
Register the bundle in config/bundles.php (Symfony 4+):
return [
// ...
CRS\SendgridBundle\SendGridBundle::class => ['all' => true],
];
Configuration:
Add to .env:
SEND_GRID_KEY=your_sendgrid_api_key
SEND_GRID_STATUS=true
(Legacy Symfony 3.x: Add to config/packages/send_grid.yaml or config.yml under send_grid key.)
First Use Case: Send a plain-text email:
use CRS\SendgridBundle\Mail\SendMail;
$sendmail = new SendMail();
$sendmail->setFrom('sender@example.com')
->setTo('recipient@example.com')
->setSubject('Test Email')
->setBody('Hello, this is a test email.')
->sendMail('text/plain');
Instantiation & Configuration:
Use dependency injection (DI) for SendMail in controllers/services:
public function __construct(private SendMail $sendmail) {}
Template-Based Emails: For dynamic templates (SendGrid’s Dynamic Template feature):
$sendmail->setTemplate('d-12345678')
->setSubstitute(['name' => 'John', 'count' => 5]);
Attachments:
$sendmail->addAttachment([
__DIR__.'/file1.pdf',
__DIR__.'/file2.jpg'
]);
CC/BCC:
$sendmail->setCc(['cc@example.com'])
->setBcc(['bcc@example.com']);
Symfony Mailer Bridge:
For modern Laravel-like workflows, pair with symfony/mailer (if possible) to leverage Symfony’s Message class:
use Symfony\Component\Mime\Email;
use Symfony\Component\Mailer\MailerInterface;
$email = (new Email())
->from('sender@example.com')
->to('recipient@example.com')
->subject('Test')
->text('Hello');
$mailer->send($email); // Requires custom SendGrid transport.
Event Listeners: Trigger emails on domain events (e.g., user registration):
// In a service
$this->sendmail->setFrom('noreply@example.com')
->setTo($user->email)
->setSubject('Welcome!')
->setBody("Welcome, {$user->name}!")
->sendMail('text/plain');
Batch Processing: Queue emails for async sending (use Laravel’s queue system or Symfony’s Messenger):
$this->sendmail->sendMail('text/plain'); // Dispatch to queue.
Deprecated Symfony 3.x:
SendMail class.Configuration Quirks:
status in send_grid config is a boolean (true/false), but the README uses %send_grid_status% (env var). Ensure .env matches:
SEND_GRID_STATUS=true
key and status in config. Missing values will throw errors.Attachment Limits:
Template Substitutions:
setSubstitute() method uses SendGrid’s Dynamic Template syntax (<%variable%>). Mismatched keys (e.g., '{{name}}') will fail silently.Error Handling:
try-catch:
try {
$sendmail->sendMail('text/plain');
} catch (\Exception $e) {
\Log::error("SendGrid failed: " . $e->getMessage());
// Retry or notify admin.
}
Enable SendGrid Logging:
Add to config/packages/monolog.yaml:
handlers:
sendgrid:
type: stream
path: "%kernel.logs_dir%/sendgrid.log"
level: debug
Test with Sandbox Mode: Use SendGrid’s sandbox mode to test without real emails:
SEND_GRID_SANDBOX_MODE=true
Validate API Key: Test connectivity via cURL:
curl -X GET "https://api.sendgrid.com/v3/user/account" \
-H "Authorization: Bearer $SEND_GRID_KEY"
Custom Transport:
Extend the bundle’s SendGridTransport (if exposed) to add features like:
X-SMTPAPI for SendGrid’s SMTP API).Event Dispatching: Trigger events before/after sending (e.g., log emails):
// In SendMail class (override if possible)
public function sendMail($contentType) {
$this->dispatchEvent('mail.sending', $this);
// ... original logic ...
$this->dispatchEvent('mail.sent', $this);
}
Fallback Mechanism: Implement a fallback to another provider (e.g., Mailgun) if SendGrid fails:
try {
$sendmail->sendMail('text/plain');
} catch (\Exception $e) {
$fallbackMailer->send($email); // Use Symfony Mailer or PHPMailer.
}
Local Development:
Mock the SendMail class for testing:
// tests/TestSendMail.php
class TestSendMail extends SendMail {
public function sendMail($contentType) {
// Assert properties, then mock success/failure.
}
}
How can I help you explore Laravel packages today?