はじめに
- YUZURIHAの松村です。
- Laravel標準のメール送信機能を、SendGridに対応するように実装しました。
- その際にハマったポイントなどについてご紹介します。
SendGridを使う2つの方法
- LaravelでSendGridを使ってメール送信を実装する方法としては、以下の2つがあります。
公式SDK
- SendGrid公式によるPHP用のSDKです。
- SendGridの各APIが操作可能で、メール送信だけでなく統計データの取得やリスト管理なども行えます。
- Laravel標準のメール機能とは独立しているため、独自の書き方が必要になります。
- 本稿では、こちらの具体的な使い方などは割愛します。
Symfony Mailerのブリッジ
- Laravel(Symfony)標準のメール機能を、SendGridに対応させるためのブリッジです。
- メール送信のみが可能です。
- 本稿では、こちらを使う方法について説明します。
バージョン
- 前提として、LaravelとSymfony Mailerブリッジのバージョンは以下で行いました。
-
laravel/framework- v12.44.0
-
symfony/sendgrid-mailer- v8.0.0
configと.envの設定
- まず
symfony/sendgrid-mailerをcomposer requireしたら、configと.envにそれぞれ以下の通り設定します。
config/mail.php
'sendgrid' => [
'transport' => 'sendgrid',
'key' => env('SENDGRID_API_KEY'),
],
.env
MAIL_MAILER=sendgrid
SENDGRID_API_KEY=SendGridの自分のアカウントのAPIキー
AppServiceProviderへの登録
- 次に、
AppServiceProviderへの登録を行います。 - デフォルトではSendGrid用のドライバは登録されていないので、メーラーを拡張して登録する必要があります。
app/Providers/AppServiceProvider.php
use Illuminate\Support\Facades\Mail;
use Symfony\Component\Mailer\Bridge\Sendgrid\Transport\SendgridTransportFactory;
use Symfony\Component\Mailer\Transport\Dsn;
// ...
public function boot(): void
{
Mail::extend('sendgrid', function (array $config) {
return (new SendgridTransportFactory())->create(
new Dsn(
'sendgrid+smtp',
'default',
$config['key']
)
);
});
}
-
AppServiceProviderへ登録しないままメール送信すると、以下のエラーが発生するのでご注意ください。
local.ERROR: InvalidArgumentException: Unsupported mail transport [sendgrid]. in /var/www/app/vendor/laravel/framework/src/Illuminate/Mail/MailManager.php:177
Web APIでメール送信する場合
- ここまでは、SMTPによる送信について記載しました。
- SMTPではなくSendGridのWeb API経由で送信する場合は、以下の対応が必要になります。
AppServiceProviderへの登録
- まず、
AppServiceProviderへの登録の際にapiであることを明示的にします。
app/Providers/AppServiceProvider.php
public function boot(): void
{
Mail::extend('sendgrid', function (array $config) {
return (new SendgridTransportFactory())->create(
new Dsn(
'sendgrid+api',
'default',
$config['key']
)
);
});
}
symfony/http-clientのインストール
- また、APIを叩くHTTPリクエストを飛ばすために
symfony/http-clientが必要になるので、こちらもcomposer requireしましょう。- Laravelには標準で、
GuzzleというHTTPクライアントが入っています。 - しかしメール機能はSymfony側の機能なので、
Guzzleとは別でSymfony用のHTTPクライアントが必要になります。
- Laravelには標準で、
-
symfony/http-clientをインストールしないままメール送信すると、以下のエラーが発生するのでご注意ください。
local.ERROR: LogicException: You cannot use "Symfony\Component\Mailer\Transport\AbstractHttpTransport" as the HttpClient component is not installed. Try running "composer require symfony/http-client". in /var/www/app/vendor/symfony/mailer/Transport/AbstractHttpTransport.php:37
最後に
- SendGridの公式SDKを使う方法でも良いのですが、以下のようなケースではSymfony Mailerブリッジの方が向いてるなと思いました。
- メール送信をするだけで、統計データの取得やリスト管理は行わない。
- SendGrid以外の方法でも送信したりログ出力する。
- 例えば本番環境はSendGridによる送信・開発環境はログ出力にする場合、環境変数によって切り替えるだけで良いので楽です。
- 公式SDKを使っていると、自分でビジネスロジックを書いて切り替えるように実装しなければなりません。
- やはり方法が複数ある場合は、条件に応じて的確に技術選定することが大切ですね。