1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Laravel7フォームでお問い合わせが送信されたらサイト運営者にメールで知らせる

Posted at

やりたいこと

要件

  • コンタクトフォームから名前、メアド、メッセージを記入して送信すると、その内容がサイト運営者にメールが飛ぶ。
  • アカウント登録がなくてもゲストでも送信できる。
  • DBは使用しない。
  • Heroku、ローカル開発環境(MAMP)両方で機能する。

初めてなので、まずはシンプルなものを実装。今後、入力確認画面とかエラーメッセージとか色々応用出来たらいいなと思っています。

やるべきことを俯瞰します

  • Mailtrapの準備
  • Laravelアプリ内のメールの環境設定
  • ビューの作成(xxx.blade.php)
  • コントローラの設定(XxxController.php)
  • ルートの設定(web.php)
  • Mailableの準備(XxxXxx.php)
  • メールのテンプレート作成(xxx.blade.php)

やってみた

Mailtrapの準備

Mailtrapとは、Webアプリで使用するメールを助けてくれるサービスです。
https://mailtrap.io/ でサインアップ(GitHub連携などで一瞬で登録出来ます)。

Laravelアプリ内のメールの環境設定

Mailtrapを開いて、Inboxes→歯車マーク→SMTP Settingsタブへ。
スクリーンショット 2020-09-22 14.04.49.png
Integrationsという箇所を見つけたら、ドロップダウンリストからLaravelを選択。その下に表示されるCredentialsのSMTPのUsernameとPasswordを控えます。
ローカル開発環境から設定します。.envファイルを開き、下記のように修正。(隠れファイルなのでご注意。隠しファイルを表示するにはMacならCommand + Shift + . 同時押し)

.env
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=Mailtrapを見てここ修正
MAIL_PASSWORD=Mailtrapを見てここ修正
MAIL_ENCRYPTION=Mailtrapを見てここ修正
MAIL_FROM_ADDRESS=お好みで修正
MAIL_FROM_NAME="${APP_NAME}" ここも適宜修正

次にHeroku用の環境。上記設定だけでは、Herokuでは機能しません。それもそのはず。私の場合、.envファイルを.gitignoreファイルに入れてgitの管理対象外にしているからです。
なので、Herokuの環境設定をすればOKです。方法は2つあって、コマンドラインを使う方法とHerokuサイト上でGUIで入力する方法です。HerokuサイトならSettingsタブを開いて、Config VarsでReveal Config Varを押すと入力欄が出てきます。

コマンドラインなら下記のようなコマンドを。ちなみに私は、Laravelアプリのディレクトリにいる状態で行いました。.envファイルで行った設定をそのまんまHerokuにも設定してあげればよいですね。

$ heroku config:set MAIL_HOST=smtp.mailtrap.io
$ heroku config:set MAIL_USERNAME=Mailtrapを見てここ修正
$ heroku config:set MAIL_PASSWORD=Mailtrapを見てここ修正
$ heroku config:set MAIL_ENCRYPTION=Mailtrapを見てここ修正
$ heroku config:set MAIL_FROM_ADDRESS=お好みで修正

余談で、下のようにconfig/mail.appファイルを編集するというやり方もありますが、機密情報がダダ漏れしてしまうのでやめた方が良さそうです。

mail.app
   'mailers' => [
        'smtp' => [
            'transport' => 'smtp',
            'host' => env('MAIL_HOST', 'smtp.mailtrap.io'), //ここをMailtrapに変更
            'port' => env('MAIL_PORT', 587),
            'encryption' => env('MAIL_ENCRYPTION', 'tls'),
            'username' => 'Mailtrapを見てここ修正', //ここ修正
            'password' => 'Mailtrapを見てここ修正', //ここ修正
            'timeout' => null,
            'auth_mode' => null,
        ],

ビューの作成(xxx.blade.php)

resources/views/contact/contact.blade.phpという形で作成しました。フォームの作成例です。必要最小限の表記にしています。

contact.blade.php
<form action="process" method="post">
  @csrf
  <div>
    <label for="name">お名前</label>
    <input type="text" name="name" id="name">
  </div>
  <div>
    <label for="email">メールアドレス</label>
    <input type="email" name="email" id="email">
  </div>
  <div>
    <label for="message">お問い合わせの内容</label>
    <textarea name="text" cols="40" rows="8" id="message"></textarea>
  </div>
  <div>
    <input type="submit" value="送信する">
  </div>
</form>

ポイント

  • @csfr:Laravelで必須のCSRF対策。(Cross Site Request Forgeryの略)
  • formタグのaction属性:フォーム送信後のアドレスになる
  • formタグのmethod属性:post。HTTPのPOSTメソッドに相当。フォームのデータをサーバーに送信する。
  • inputやtextareaタグのname属性:入力値の値はこのnameと一緒にサーバーに送信される重要な属性。

コントローラの設定(XxxxController.php)

コマンドラインで、ファイルを作成します。あるサイトでは、Laravel規約では複数形でないといけないと書いてましたが、某教科書は単数形なので教科書に倣います。

$ php artisan make:controller ContactController

下記のように編集していきます。

ContactController.php
<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;//追記
use App\Mail\ContactMail; //追記。後に作るMailable。後述。

class ContactController extends Controller
{
    //contact.blade.php表示
    public function index()
    {
        return view('contact.contact'); //'contactフォルダの中のcontace.blade.php'
    }
    //メール送信
    public function process(Request $request)
    {
        $request->validate([ //バリデーション
            'name'     => 'required',
            'email'    => 'required|email',
            'text'     => 'required',
        ]);
        $input = $request->all();
        unset($input['_token']); //CSRF非表示フィールド_token削除
        Mail::to('送信先メアド')->send(new ContactMail('contact.mail', 'お問い合わせを受信しました', $input));
        return redirect('/');
    }
}

ルートの設定(web.php)

web.php
//Contactページの表示
Route::get('contact', 'ContactController@index');

//フォームの受け取りとメール送信
Route::post('process', 'ContactController@process'); //先のformタグのaction属性はこの第一パラメータと関係する

Mailableクラスの準備

Mailableとは、Laravelアプリが送信するメールを操作するクラスです。詳しくは公式ドキュメントを。今回はContactMail.phpという名前で作成しました。

php artisan make:mail ContactMail

app/MailディレクトリにContactMail.phpが生成されました。

ContactMail.php
<?php
namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class ContactMail extends Mailable
{
    use Queueable, SerializesModels;

    public $data; //追記
    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($template, $subject, $data)
    {
        $this->subject = $subject; //件名
        $this->data = $data; //フォームで受信したデータ
    }

    /**
     * Build the message.送信するメールの設定はbuildメソッド
     * 
     * @return $this
     */
    public function build()
    {
        return $this->from('メールの発信先アドレス')//fromメソッドでメールの送信メアドを設定。
                    ->view('contact.mail');//メールのテンプレートを指定。ここではcontactフォルダのmail.blade.phpを指定。
    }
}

メールのテンプレート作成(xxx.blade.php)

views/contact/mail.blade.php
<head>
  <style>
    h1 {
      font-size: 18px;
    }
    p {
      font-size: 14px;
    }
  </style>
</head>
<body>
  <h1>{{$data["name"]}}様からの、お問い合わせを受信しました。</h1>
  
  <p>メールアドレス: {{$data["email"]}}</p>
  <p>内容:  {{$data["text"]}}</p>
</body>

ポイントは、Mailableクラスから受け取ったデータを{{$data[""]}}でフォームデータを表示できるという点でしょう。

最後に

これでうまく設定できていれば、フォームで送信すると、Mailtrapの受信箱でメールを受信することができます。
スクリーンショット 2020-09-22 20.59.17.png

何かご指摘、アドバイスあればよろしくお願い申し上げます。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?