How to send transactional email with Laravel and SendGrid
In this post, I have taken a Contact Us form as an example to send a smart email with Laravel and SendGrid. So, when a user completes the contact us form, the Send Grid will send the transactional email to the user.
Before you begin coding, make sure the following actions are done in SendGrid.
- Template is created for Contact us email,
- Placeholders/substitution are all set and you have a template id to use it on Laravel
- Authenticated your domain name e.g. newsletter@yourdomain.com
- Generated the api key
Add a send grid package to Laravel
Install the Send Grid packaged by issuing the Composer command below:
composer require sendgrid/sendgrid
Add the api key into your .env file
SENDGRID_API_KEY=API-KEY-IN-HERE
Create a Laravel mailable classes
Create a new file BaseEmail.php running the following command in your terminal:
php artisan make:mail BaseEmail
This file will be created in app/mail directory. Update the app/mail/BaseEmail.php as below:
<?php namespace App\Mail; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Mail\Mailer; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\Log; use SendGrid\Mail\Mail; use SendGrid\Mail\TypeException; class BaseEmail extends Mailable { use Queueable, SerializesModels; /** * The template id of the email template in send grid * @var */ protected $intTemplateId; /** * Substitutions that will apply to the text * and html content of the body of your email, * in addition to the subject and reply-to parameters * @var */ protected $arrSubstitutions = []; /** * Create a new message instance. * * @param array $arrSubstitutions */ public function __construct(array $arrSubstitutions) { $this->arrSubstitutions = $arrSubstitutions; } /** * Send a transactional email * * @param Mailer $mailer * @return void * @throws TypeException */ public function send(Mailer $mailer) { $mail = new Mail(); $mail->setFrom("newsletter@yourRegisteredDomain.co.uk", "Sender Name"); $mail->setTemplateId($this->intTemplateId); $mail->addTo($this->to[0]["address"], null, $this->arrSubstitutions); $sendgrid = new \SendGrid(env('SENDGRID_API_KEY')); try { $sendgrid->send($mail); } catch (\Exception $e) { Log::error('Something wrong with SendGrid api: '. $e->getMessage()); } } }
Now, you have the base class, all you have to do is create a new mail class for each Send Grid template you would like to use by extending this BaseEmail class. ContactFormEmail.php class has been created as an example. Run the following command in your terminal to create this file:
php artisan make:mail ContactFormEmail
Update the app/mail/ContactFormEmail.php by adding the template id of a contact us email template provided by Send Grid as below:
<?php namespace App\Mail; use Illuminate\Bus\Queueable; use Illuminate\Queue\SerializesModels; class ContactFormEmail extends BaseEmail { use Queueable, SerializesModels; /** * The template id provided by send grid * @var string */ protected $templateId = 'd-7e98d51f48f74d789bd14m02826n52d9'; }
Because placeholders in Send Grid are case sensitive, therefore when you set the substitution key in mailable class, ensure they are exactly the same as in Send Grid templates.
You can use the ContactFormEmail class as below. I have used it in ContactController.php. When user submit the forms, the index method receives the form values in ContactController.
<?php namespace App\Http\Controllers; use Mail; use App\Mail\ContactFormEmail; class ContactController extends Controller { /** * Sends the thank you message to user and display the thank you page * @param Request $request * @return Application|RedirectResponse|Redirector */ public function index(Request $request) { $arrSubstitutions = []; // The following substitution key must be exactly same as // set up in template in send grid e.g {{firstName}} $arrSubstitutions['firstName'] = $request->post('firstName'); $arrSubstitutions['lastName'] = $request->post('lastName'); $arrSubstitutions['message'] = $request->post('firstName'); $to = 'whoever@gmail.com'; $email = new ContactFormEmail($arrSubstitutions); Mail::to($to)->queue($email); return "Whatever you want, may be redirect to thank you for contact us view page" } }
Hope that was helpful.