Twilio SendGridを使ってLaravelでWebベースのメール送信機能を構築する方法
- 2020年9月24日
- by SendGrid
- Category: 技術ネタ

この記事は How to Build a Web-Based Email Client in Laravel PHP using Twilio SendGrid の抄訳です。
新しいアプリケーションを構築し一般に公開する際は、非常に神経を使うものです。特に、開発やマーケティングの初期段階では、ユーザと継続的に連絡を取り合うことが大切です。
このコミュニケーションの手段としてメールは欠かせません。メールは、新機能や不具合の修正をユーザへ知らせたり、非アクティブなユーザをフォローアップしたりするのに最適です。
そこで、このチュートリアルでは、既存のLaravelアプリケーションにWebベースのメール送信機能を追加する方法を見ていきます。このチュートリアルを終了すると、LaravelとTwilio SendGridを利用したメールシステムを構築できるようになります。
必要なもの
このチュートリアルで必要なものは以下のとおりです。
|
・基本的なLaravelの知識 ・Laravelのインストール ・Composerのグローバルインストール ・MySQLのセットアップ ・SendGridのアカウント |
はじめに
はじめに、今回のアプリケーション用の新しいLaravelプロジェクトを作成します。このとき、Laravel InstallerとComposerのどちらを利用しても構いませんが、本チュートリアルでは前者を使います。もしLaravel Installerをインストールしていなければ、ドキュメントで手順を確認してください。インストールできたら、ターミナルで以下のコマンドを実行します。
$ laravel new custom-mail-system
ここで、SendGridへのアクセスにはSendGrid PHPライブラリを利用します。プロジェクトディレクトリで以下のコマンドを実行し、Composer経由でライブラリをインストールします。
$ composer require "sendgrid/sendgrid"
SendGridライブラリでは、メール送信のためにAPIキーを利用します。APIキーはダッシュボードで作成することができます。

まだAPIキーを持っていない場合は新しく作成しましょう。作成に成功したら、表示される文字列を安全な場所にコピーしておきます。APIキーは一度しか表示されないのでご注意ください。

次に、.envファイルの環境変数にAPIキーを追加します。ファイルの末尾に以下を追記してください。
SENDGRID_API_KEY={YOUR API KEY}
データベースのセットアップ
次のステップは、データベースのセットアップです。このチュートリアルではMySQLを利用します。まだローカルマシンでMysqlの設定ができていない場合は、ダウンロードページにアクセスしてインストールを進めます。
アプリケーション用のデータベースを作成するには、MySQLクライアントへのログインが必要です。以下のコマンドを実行します。
$ mysql -u {your_user_name}
補足:MySQLインスタンスにパスワードを設定している場合は、コマンドに -p オプションを付けます。
以下のコマンドを実行し、データベースを作成します。
mysql> create database custom-mailing;
mysql> exit;
usersテーブルのマイグレーション
Laravelでは、次のような基本的なスキーマを含むusersテーブルのマイグレーションが最初から準備されています。
/** * Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
このコードを見ると、本アプリケーションに必要なフィールド(emailとname)が最初から存在するので、スキーマを編集する必要はありません。このマイグレーションはまだデータベースにコミットされていないため、以下のコマンドを実行します。
$ php artisan migrate
マイグレーションファイルのup()メソッドが実行されると、ファイルに列挙したフィールドを持つusersテーブルが作成されます。
Usersテーブルへの初期データの投入
テーブルが作成できたら、いくつかユーザ情報を登録しておきます。データの投入にはseedersを使うのが便利です。seederクラスを作るには、以下のコマンドを実行します。
$ php artisan make:seeder UsersTableSeeder
すると、database/seeds/にUsersTableSeederというseederクラスが作成されます。このファイル( database/seeds/UsersTableSeeder.php )を開いて、以下のように編集しましょう。
<?php
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Faker\Generator as Faker;
use Illuminate\Support\Facades\Hash;
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run(Faker $faker)
{
DB::table("users")->insert([
[
'name' => $faker->name,
'email' => $faker->unique()->safeEmail, //use real email here
'email_verified_at' => now(),
'password' => Hash::make($faker->password()), // assword
],
[
'name' => $faker->name,
'email' => $faker->unique()->safeEmail, //use real email here
'email_verified_at' => now(),
'password' => Hash::make($faker->password()), // password
],
[
'name' => $faker->name,
'email' => $faker->unique()->safeEmail, //use real email here
'email_verified_at' => now(),
'password' => Hash::make($faker->password()), // password
],
]);
}
}
補足:email fakerのメールアドレスは、実際にテストに使うアドレスへ置き換えておきます。
以下のコマンドを実行してデータを作成します。
$ php artisan db:seed --class=UsersTableSeeder
メール送信
ここまでの手順で、データベースのセットアップとデータの登録、SendGrid SDKのインストールができました。それでは、ビジネスロジックの実装に着手しましょう。まずは、メール送信機能を実装するcontrollerクラスが必要です。以下のコマンドを実行します。
$ php artisan make:controller MailingController
作成されたMailingController( app/Http/Controllers/MailingController.php )を以下のように編集します。
<?php
namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\Request;
use SendGrid;
class MailingController extends Controller
{
public function sendMail(Request $request)
{
$validated = $request->validate([
'from' => 'required|email',
'users' => 'required|array',
'users.*' => 'required',
'subject' => 'required|string',
'body' => 'required|string',
]);
$from = new \SendGrid\Mail\From($validated['from']);
/* Add selected users email to $tos array */
$tos = [];
foreach ($validated['users'] as $user) {
array_push($tos, new \SendGrid\Mail\To(json_decode($user)->email, json_decode($user)->name));
}
/* Sent subject of mail */
$subject = new \SendGrid\Mail\Subject($validated['subject']);
/* Set mail body */
$htmlContent = new \SendGrid\Mail\HtmlContent($validated['body']);
$email = new \SendGrid\Mail\Mail(
$from,
$tos,
$subject,
null,
$htmlContent
);
/* Create instance of Sendgrid SDK */
$sendgrid = new SendGrid(getenv('SENDGRID_API_KEY'));
/* Send mail using sendgrid instance */
$response = $sendgrid->send($email);
if ($response->statusCode() == 202) {
return back()->with(['success' => "E-mails successfully sent out!!"]);
}
return back()->withErrors(json_decode($response->body())->errors);
}
}
sendMail()のメソッドがメールを送るおまじないです!バリデーションに成功したら、SendGridのsend()メソッドにデータを渡す準備をします。ここでは、配列を使ってもライブラリのhelperクラスを使っても構いませんが、helperクラスを使った方が必要なオブジェクト(From, To, Subject, Content)を簡単に生成できます。
データの準備ができたら、リクエストボディに格納するオブジェクトを生成するためSendGrid\Mail\Mailクラスを使います。このクラスは引数を5つ取ります( from, to, subject, plainTextContent, htmlContent )。続くSendGridクラスのインスタンスは、先ほど準備したAPIキーを渡して初期化します。
ここまでできたら、send()メソッドを使って$tos配列に格納したメールを送信します。send()メソッドの引数は、先ほど生成したSendGrid\Mail\Mailクラスのオブジェクト1つのみです。send()メソッドはstatusCodeとbodyを含むレスポンスを返します。リクエストが成功すると202のstatusCodeが返り、送信成功のメッセージとともにsendmailビューへリダイレクトします。それ以外のコードが返ると、エラーメッセージとともに前のページへ戻ります。
ビューの構築
以上でメールの送信ロジックは完成です!後はユーザが操作する画面が必要です。ここでは、メールの情報を入力する簡単なフォームを準備します。デフォルトのウェルカムページ( resources/views/welcome.blade.php )を開き、以下の内容で置き換えましょう。
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Custom Mail Portal With Sendgrid</title>
<!-- Styles -->
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="jumbotron">
@if (session('success'))
<div class="alert alert-success">
{{ session('success') }}
</div>
@endif
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<div class="row">
<div class="col">
<div class="card">
<div class="card-header">
Send Custom Mail
</div>
<div class="card-body">
<form method="POST" action="/sendmail">
@csrf
<div class="form-group">
<label>From</label>
<input required name="from" value="{{getenv('MAIL_FROM')}}" class="form-control"> </div>
<div class="form-group">
<label>Subject</label>
<input required name="subject" class="form-control">
</div>
<div class="form-group">
<label>Select users to send mail to</label>
<select required name="users[]" multiple class="form-control">
@foreach ($users as $user)
<option value="{{$user}}">{{$user->name}} - {{$user->email}}</option>
@endforeach
</select>
</div>
<div class="form-group">
<label>Message</label>
<textarea required name="body" class="form-control" rows="3"></textarea>
</div>
<button type="submit" class="btn btn-primary">Send Mail(s)</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
selectタグについて詳しく見てみると、optionの値が$usersプロパティから取得されていることが分かります。このとき、$userのデータをビューに渡しているのではなく、web.phpを直接参照している形になります。これを変更するには、app/Http/Controllers/MailingController.phpに以下の内容を記載します。
public function index()
{
return view('welcome', ['users' => User::all()]);
}
このメソッドは、usersテーブルの全データが格納された配列を持つsendmailビューを返します。
ルーティングの設定
以上で主要な機能は完成です。最後に、アプリケーションを正しく動作させるためルーティングを設定します。routes/web.phpを開き、以下のように編集してください。
<?php
use App\User;
use Illuminate\Support\Facades\Route;/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', 'MailingController@index');
Route::post('/sendmail', 'MailingController@sendMail');
アプリケーションのテスト
それでは、完成したLaravelプロジェクトをテストしてみましょう!以下のコマンドを実行します。
$ php artisan serve
このコマンドによって、Laravelアプリケーションがローカルホストの8000番ポートで起動します。ブラウザでコマンド実行後に表示されるリンクにアクセスすると、このような画面が表示されます。

フォームに必要事項を入力して「Send Mails」ボタンを選択します。問題なければ、入力した内容が記載されたメールが指定した宛先に届きます。
終わりに
このチュートリアルでは、メール送信システムの構築方法と、Twilio SendGrid SDKを使って複数の宛先にメール送信する方法を学びました。今回のソースコードをおさらいしたい方は、Githubもチェックしてください。
また、未登録ユーザへのメール送信に対応することで、このアプリケーションをさらに進化させることができます。ぜひお試しください。


