LaravelからSendGridを使ってメールを送信する方法!

LaravelからSendGridを使ってメールを送信する方法! Laravel

LaravelからSendGridを使ってメールを送信する方法をまとめてみました。
この記事では、Laravel(バージョン8)からSendGridを使用して、テキストメールを送信するまでをサンプルコードを付けて解説しています。

ここでは、既にLaravel環境の構築が終わっていて、メール送信するフォームまで用意している前提で書いています。
公式のブログの内容をさらにわかりやすく書いたつもりです。

LaravelからSendGridを使用するには?

SendGridはメールを配信してくれるサービスです。
SendGridのAPIに対して、データを投げることでメール送信を行ってくれます。
Laravelから使用できるライブラリも用意されているので、実装するのも簡単です。

これによって、自身でメールサーバーを準備する必要がなくなります。
また、送信したメールの数なども管理画面から下記のように確認することができ便利です。

SendGridを使う準備

SendGridを使うためには、まずサービスへのアカウント登録が必要です。
無料で登録して使い始めることが可能です。

無料で使える上限と料金について

無料の場合は月に12,000通までという上限があります。
そこまでメールを送る予定がない場合や、スモールスタートでサービスを開始したい場合は、まずは無料からでいいのではないでしょうか。
料金についてはこちらに書いています。
料金 | SendGrid
SendGridは12,000通/月まで「無料」で利用できます。送信通数に応じてプランを変更することも可能です。

アカウントを作る

アカウントの作成はこちらから行うことができます。

迷惑メールやフィッシング詐欺などに使われないように審査がありますので、正確な情報を入力しておきましょう。
私は送信元に適当なアドレスを入れていて、アカウント作成時に注意されてしまいました😅

SendGridのライブラリをインストールする

Laravelの対象ディレクトリに移動した後に下記のコマンドで、SendGridのライブラリをインストールします。

$ composer require "sendgrid/sendgrid"

実行すると、下記のようにインストールされます。

$ composer require "sendgrid/sendgrid"
Using version ^7.9 for sendgrid/sendgrid
./composer.json has been updated
Running composer update sendgrid/sendgrid
Loading composer repositories with package information
Updating dependencies
Lock file operations: 3 installs, 0 updates, 0 removals
// --- 省略 ---
Discovered Package: nunomaduro/collision
Package manifest generated successfully.
68 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

SendGridのAPIキーの準備

SendGridでメールを送信するときにはユーザーが管理画面から作成したAPIキーを使います。
APIキーの準備とLaravelの設定について書いています。

APIキーを準備する

左のメニューからAPI Keysを選択します。
SendGridのAPI Keyメニュー

キーが既に作られている場合は下記のAPI Keys画面に一覧表示されます。
「Create API Key」ボタンを押下して、キーの作成を開始します。
SendGridのCreate API Keyボタン

下記のような画面が表示されます。まず、キーに適当な名前をつけます。
キーを使用してアクセスできる権限が選べるようです。
今回はFull Accessを使用しました。

キーが発行されるので、コピーして控えておきます。

Laravelの設定ファイル(.env)にAPIキーを設定する

控えたキーをLaravelの設定ファイル(.env)に下記のように書いておきます。

SENDGRID_API_KEY={取得したAPIキーを記載する}

SendGridメール送信用のコントローラーを用意する

下記のコマンドを使用して、送信用のコントローラーを作成します。

$ php artisan make:controller MailController

MailController.phpの内容を下記のように記載します。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use SendGrid;
use SendGrid\Mail\Mail;
use \Symfony\Component\HttpFoundation\Response;

class MailController extends Controller
{
    public function index() {
        return view('mail');
    }

    public function send(Request $request) {
        $request->validate([
            'email'    => 'required',
            'subject'  => 'required',
            'contents' => 'required',
        ]);

        $email = new Mail();
        $email->setFrom('laravel-test@example.com', 'ララベルメールテストチーム');
        $email->setSubject($request->subject);
        $email->addTo($request->email);
        $email->addContent("text/plain", $request->contents);

        $sendgrid = new SendGrid(env('SENDGRID_API_KEY'));

        $response = $sendgrid->send($email);
        if ($response->statusCode() == Response::HTTP_ACCEPTED) {
            return view('mail', ['successMessage' => '送信できました!']);
        } else {
            return view('mail', ['errorMessage' => '送信失敗しました!']);
        }
    }
}

解説

indexメソッドを呼ぶと、画面を表示します。
表示する画面は次項で作成します。

次にsendメソッドです。
こちらの方でメールを送信します。

最初に渡されたパラメータをバリデーションします。
その後に、Mailクラスをnewして、SendGridで送信するメールの内容のオブジェクトを作成しています。

$email = new Mail();
$email->setFrom('laravel-test@example.com', 'ララベルメールテストチーム');
$email->setSubject($request->subject);
$email->addTo($request->email);
$email->addContent("text/plain", $request->contents);

今回は$emailという名前で作りました。

$email->setFromで送信元のメールアドレスを設定することができます。
左の方が送信元メールアドレスで、右が送信元メールアドレスの代わりに表示される名前です。

$email->setSubjectは件名です。
今回はリクエストの内容をそのまま設定しています。画面から送られてきた件名がそのまま使われます。

$email->addToは送信先です。
こちらも今回はリクエストの内容をそのまま設定しました。画面から送られてきた送信先がそのまま使われます。

$email->addContentでメールの内容を設定します。
第1引数がメールの種類です。
今回は”text/plain”としてテキストメールにしました。

第2引数にメールの内容を設定します。
リクエストで送られたメール本文を設定しています。

そして、メール送信のためにSendGridをnewしています。
ここで、「.env」に設置したAPIキーを指定していますね。

$sendgrid = new SendGrid(env('SENDGRID_API_KEY'));

この後に$sendgrid->send($email)と呼ぶことで、メールが送信されます。
作成したメールオブジェクト($email)が設定されていますね。

$response->statusCode()で送信状態が分かります。
202(Response::HTTP_ACCEPTED)が帰ってきていたら完了なので、「送信できました!」というメッセージと共に初期画面を表示し直しています。
それ以外ならエラーで「送信失敗しました!」というメッセージを初期画面に表示します。

また、送信元アドレスや送信元名なども「.env」に定義してあげると良いですね。

SendGridメール送信用の画面(blade)を作成する

mail.blade.phpという名前で、メールを送信画面を作成しました。

<!DOCTYPE html>
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
    </head>
    <body>
        @if(!empty($successMessage))
            <div class="alert alert-success" role="alert">
                {{ $successMessage }}
            </div>
        @endif
        @if(!empty($errorMessage))
            <div class="alert alert-danger" role="alert">
                {{ $successMessage }}
            </div>
        @endif
        <div class="card m-5">
            <div class="card-header">メール送信</div>
            <div class="card-body">
                <form method="post" action="{{ route('mail.send') }}">
                    @csrf
                    <div class="mb-3">
                        <label for="email" class="form-label">メールアドレス</label>
                        <input type="email" class="form-control" id="email" name="email">
                    </div>
                    <div class="mb-3">
                        <label for="subject" class="form-label">件名</label>
                        <input type="text" class="form-control" id="subject" name="subject">
                    </div>
                    <div class="mb-3">
                        <label for="contents" class="form-label">内容</label>
                        <textarea class="form-control" id="contents" name="contents" style="min-height:15em"></textarea>
                    </div>
                    <div class="d-flex justify-content-center">
                        <button type="submit" class="btn btn-success">送信する</button>
                    </div>
                </form>
            </div>
        </div>
    </body>
</html>

解説

画面のCSSフレームワークはbootstrap5を使ってみました。

最初の方で、まず成功した場合とエラーだった場合でメッセージを出しています。
成功した場合は$successMessageに値が入るので、alert-successクラスが付加された緑のアラートが出ます。
失敗した場合は赤色のアラートです。

@if(!empty($successMessage))
    <div class="alert alert-success" role="alert">
        {{ $successMessage }}
    </div>
@endif

その下にcardクラスを使用して、送信するフォームを書きました。
メールアドレス・件名・内容を入力して、送信ボタンを押すというものです。

フォームの送信方式はPOSTで、アクションはrouteヘルパを使ってmail.sendで定義しています。
@csrfはCSRF対策のため、LaravelでPOSTするときは必須で入れておくものです。

ルーティングを修正する

routes/web.phpを修正して、ブラウザからアクセスされた場合のルーティングを作ります。
まず、use文を使って作成したクラスを定義します。

use App\Http\Controllers\MailController

下記のルーティングを記載します。

Route::get('/mail', [MailController::class, 'index']);
Route::post('/mail/send', [MailController::class, 'send'])->name('mail.send');

解説

/mailにアクセスすると、MailControllerクラスのindexメソッドが動いて送信画面が表示されます。
/mailにアクセスする(メール送信する)と、MailControllerクラスのsendメソッドが動いてメール送信処理が行われます。

動作確認

それでは、動作を確認してみます。

/mailにアクセスすると、下記のように表示されます。
SendGridでLaravelからメールを送信するフォーム

内容を入力して、送信ボタンを押します…

送信完了しました!!

メールを確認してみると、ちゃんと届いていることが確認できました。
SendGridからLaravel経由でメールが届いた

簡単にメールを送ることができました。
システムからメールを送るときに便利なので、メールを送信する要件がある場合は一度使ってみてはいかがでしょうか。

コメント

タイトルとURLをコピーしました