[Laravel8.x] Mailgun + お名前.com + Route53 のメール送信設定方法

Laravel8.x + Mailgun + お名前.com + Route53

まず、Mailgunでカスタムドメインを設定する必要がある
そうすると、DNSに、TXT、MX、CNAMEを登録しろ、と出てくる

なるほど、これをお名前.comに登録すれば良いのね、ということで、お名前.comのDNS設定で追加して、Verify DNS Settingsを押しても一向にverifyされない。。。

何故だ? 24時間くらい待った方が良いの? 常識的にそんな訳ないよね。。お名前に問い合わせしようかな。。と考えていたが、
TXT、MX、CNAMは、お名前側ではなく、Route53のHosted zonesのcreate recordで設定して上手くいった。
設定内容は、record nameと”Enter This Value”をvalueに入れていく。

mxレコードの場合は、valueに”10 mxa.mailgun.org”と入れる。

これで、再度Verify DNS Settingsを押すと、verifyされる。

で、設定したドメインのSMTP credentialのページに行き、ログインの箇所とReset Passwordでパスワードを取得して、この内容をlaravelのenvに記載する

laravel .env
L maildriverはsmtpのままで大丈夫

MAIL_MAILER=smtp
MAIL_HOST=smtp.mailgun.org
MAIL_PORT=587
MAIL_USERNAME=postmaster@${domain name}
MAIL_PASSWORD=${domain password}
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME=""

これでOK
送信テストを行う

まあ、Amazon SESの申請が降りたから、mailgun使わなくて良いんだけど、SESの申請が落ちた時はこちらを使う。
取り敢えず、MailgunのTXT、MX、CNAMEはお名前.comではなく、Route53側で設定するということ。

mailstrapで開発してて、さあSTG、商用環境にデプロイしよか、って時にメール送信できないとか、恐怖でしかないわ、ホンマに。

[Laravel8.16.0] Mailgunを実装する

$ composer require guzzlehttp/guzzle

env

MAIL_DRIVER=mailgun
MAIL_HOST=smtp.mailgun.org
MAIL_PORT=587
MAIL_USERNAME=postmaster@sandbox*.mailgun.org
MAIL_PASSWORD=*
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"

config/mail.php
-> 特に変更なし

config/service.php

'mailgun' => [
        'domain' => env('*'),
        'secret' => env('*'),
        'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
    ],

来た! なんか色々戸惑ったけど、OK

sandbox.mgsend.net経由でもそんなに目立って悪くないように思うが、mailgunのドメイン設定もやりたい。
というか、腹減ったー 飯食うの忘れてた。

[Laravel8.16.0] Mailtrapでメール送信

$ composer require guzzlehttp/guzzle

config/mail.php

    'from' => [
        'address' => env('MAIL_FROM_ADDRESS', 'test@hpscript.com'),
        'name' => env('MAIL_FROM_NAME', 'Hpscript'),
    ],

.env

MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=${userName}
MAIL_PASSWORD=${password}
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"

$ php artisan make:mail TestMail
app/Mail/TestMail.php

    public function build()
    {
        return $this
                ->from("test@hpscript")
                ->subject("test send")
                ->view('email.test');
    }

resources/views/email/test.blade.php

test mail body

$ php artisan make:controller –resource MailController

Route

Route::get('/mail', [App\Http\Controllers\MailController::class, 'index']);

app/Http/Controllers/MailController.php

use Illuminate\Support\Facades\Mail;
use App\Mail\TestMail;

public function index()
    {
        //
        Mail::to('test@example.com')
        ->send(new TestMail());
    }

mailtrapはいいけど、実際に送れないと意味ない。
メール設計書を作成して、mailgunを使っていきます。

laravel6.xでSESの設定

### SES
Service -> Customer Engagement -> Simple Email Service
Asia Pacific (Mumbai)
左メニューのEmailAddresses -> Verify a New Email Address -> 認証
以下のような文言が表示される

Amazon SES の新規ユーザーの場合–上限緩和をまだ申請していない場合は、引き続きサンドボックス環境を使用しています。そのため、メールは確認済みのアドレスにのみ送信できます。新しいメールアドレスまたはドメインを確認するには、Amazon SES コンソールの [Identity Management] のセクションを参照してください。

Amazon Pinpoint の新規ユーザーの場合–上限緩和をまだ申請していない場合は、引き続きサンドボックス環境を使用しています。そのため、メールは確認済みのアドレスにのみ送信できます。新しいメールアドレスまたはドメインを確認するには、Amazon Pinpoint コンソールの [Settings] > [Channels] ページを参照してください。

なお、送信制限解除申請は、AWS Support -> Create Case -> Service limit increaseから送信する

### AmazonSESFullAccessのユーザ追加
IAMからAdd user
User name:${appName}-ses
Select AWS access type: Programmatic access
Permissions: AmazonSESFullAccess

### .env

MAIL_DRIVER=ses
MAIL_FROM_ADDRESS=${ses認証のメールアドレス}

SES_KEY=
SES_SECRET=
SES_REGION=ap-south-1 ※munbai

### テスト実行
Error executing “SendRawEmail” on “https://email.ap-northeast-1.amazonaws.com”; AWS HTTP error: cURL error 6: Could not resolve host: email.ap-northeast-1.amazonaws.com (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)

あれ?
$ curl https://email.ap-northeast-1.amazonaws.com
curl: (6) Could not resolve host: email.ap-northeast-1.amazonaws.com

SES_REGIONをap-south-1に設定しているのに、ap-northeast-1にリクエストを送ってます。
configでsesの設定を確認してみます。

config/services.php

'ses' => [
        'key' => env('AWS_ACCESS_KEY_ID'),
        'secret' => env('AWS_SECRET_ACCESS_KEY'),
        'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
    ],

regionがAWS_DEFAULT_REGIONとなっており、さらに、keyとsecretも共通のkey, secret担っているので、AWS_DEFAULT_REFIONをmunbaiに変更します。

'ses' => [
        'key' => env('SES_KEY'),
        'secret' => env('SES_SECRET'),
        'region' => env('ap-south-1', 'us-east-1'),
    ],

$ php artisan config:clear

同時に、mailのfromを.envから取得するように変更します。

->from(env('MAIL_FROM_ADDRESS'))

SESで送信できていることが確認できます。

laravel 6.x Mailgunからメール送信する書き方

公式ドキュメント: https://readouble.com/laravel/6.x/ja/mail.html

# 前準備
### mailgun
mailgun登録
https://app.mailgun.com/

### guzzleインストール
$ php composer.phar require guzzlehttp/guzzle

※guzzleとは?
https://github.com/guzzle/guzzle
-> Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and trivial to integrate with web services.

### .env

MAIL_DRIVER=mailgun
MAILGUN_DOMAIN=**********.mailgun.org
MAILGUN_SECRET=**********

### config/mail.php
driverをsmtpからmailgunに変更

'driver' => env('MAIL_DRIVER', 'mailgun'),

### config/services.php
特に変更なし

 'mailgun' => [
        'domain' => env('MAILGUN_DOMAIN'),
        'secret' => env('MAILGUN_SECRET'),
        'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
    ],

// route, controller, bladeは省略

以上

smtpとは異なり、.envにMAILGUN_DOMAINとMAILGUN_SECRETを設定する必要がある。
services.phpのendpointはデフォルトのまま

smtpを独自に作るとなると大変だが、APIだとサクッと書ける

Laravelでgmailから送信する設定

# gmailから送信する設定
### メール送信するgoogle account
– セキュリティ->2段階認証プロセス on
– アプリパスワード->(メール, mac(or windows))を選択

### .env

MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=${domain}@gmail.com
MAIL_PASSWORD=${生成されたアプリ パスワード}
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=${domain}@gmail.com
MAIL_FROM_NAME=sample

$ php artisan config:cache

// route, controller, bladeは省略

587ポートとは?
->メール送信時に使われてきたTCP25番ポート以外で、メール送信の為の専用ポート
->25番ポートブロックでも送信可能になる

outlookでもsmtpホストがありますが、殆ど使われていないのでしょうか。

メール送信時のcontroller・mailableクラスの変数の書き方

– to, cc, bccなど宛先はcontrollerで書く
– mailableクラスのコンストラクターに引数を渡す
– constructorに初期値を設定し、callback関数でルートからプレビューを行うこともできる
– メール本文は、text, htmlどちらも可能。改行はbrタグ

### controller

use Illuminate\Support\Facades\Mail;
use App\Mail\TestMail;
public function index()
    {
        //
        $name = '山本太郎';
        $date = '2020/02/11';
        $status = '完了';
        $to = 'test@gmail.com';
        $cc = 'cc@gmail.com';
        
        Mail::to($to)
            ->cc($cc)
            ->send(new TestMail($name, $date, $status));
        return "its works";
    }

### app/Mail/TestMail.php
$ php artisan make:mail TestMail

public function __construct($name='山田太郎', $date='2020/01/01', $status='テスト')
    {
        //
        $this->title = $date . 'テスト送信';
        $this->date = $date;
        $this->name = $name;
        $this->status = $status;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this
            ->from('from@example.com')
            ->subject($this->title)
            ->view('email.test')->with([
                'name' => $this->name,
                'date' => $this->date,
                'status' => $this->status,
            ]);
    }

### view

{{ $date }}<br>
メール本文<br>
{{ $name }}さんのステータスは{{ $status}}です

### routeプレビュー時

Route::get('/send', 'MailController@index');
Route::get('/send/preview', function(){
	return new App\Mail\TestMail();
});

メールの送信方法と、メール内容の設定はMVCで切り離されているので、非常に管理しやすいように思います。

mailtrapによるテスト送信の流れ

Dev、STG環境でのメール送信にmailtrapを使用できる
https://mailtrap.io/

### 特徴
– 開発用
– Inboxに保管できるメール数の上限は50通
– Inboxはひとつだけ

### .env
Integrationsの”Laravel”の内容を記述します

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"

### make:mail
$ php artisan make:mail TestMail

app/Mail/TestMail.php が生成される

public function build()
    {
        return $this
            ->from('from@example.com')
            ->subject('テスト送信')
            ->view('email.test');
    }

### メール本文
resources/views/email/test.blade.php

メール本文

### route

Route::get('/send', 'MailController@index');

### controller
$ php artisan make:controller –resource MailController

public function index()
    {
        //
        Mail::to('test@gmail.com')
            ->send(new TestMail());
        return "its works";
    }

$ php artisan serve –host 192.168.33.10 –port 8000

mailtrapを確認すると、送信済となっています。
controllerから、メールを送る際に変数を扱いたいと思うので、続けてやっていきたいと思います。

Laravelからのメール送信

実際のアプリケーションではSMTPにAWS SESを使いますが、ここでは便宜上、mailgunを使って、仕組みを理解します。

### mailgun
https://www.mailgun.com/
sign inして、認証します。

Laravelからメールを送信する際には、.envファイルから設定します。

デフォルト

MAIL_DRIVER=mailgun
MAILGUN_DOMAIN=sandboxf*********************.org
MAILGUN_SECRET=*******************-********-********

設定ファイル
./config/mail.php
 送信元のメールアドレス、名前を設定する

'from' => ['address' => 'name@hpscript.com', 'name' => 'hpscript'],

./config/services.php

./resources/view/emails/test.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title><Document></Document></title>
</head>
<body>
	
</body>
</html>
Routeuse Illuminate\Support\Facades\Mail;

Route::get('/', function () {
    // return view('welcome');
    $data = [
    	'title'=>"hi Hpscript",
    	"content"=>"This is Laravel first mailgun mail"
    ];

    Mail::send('emails.test', $data, function($message){
    		$message->to('*****@gmail.com', '${name}')->subject('Hello, good day!');
    });

});

mailgunを使用するにはドライバを入れる
公式ドキュメント参照:https://readouble.com/laravel/*/ja/mail.html
$ php composer.phar require guzzlehttp/guzzle

./vendor/guzzle/src/Client.php

private function configureDefaults(array $config)
    {
        $defaults = [
            'allow_redirects' => RedirectMiddleware::$defaultSettings,
            'http_errors'     => true,
            'decode_content'  => true,
            'verify'          => false,
            'cookies'         => false
        ];
        // ...
      }