blastengineを使ってPHPでメールを送信する

[blastengine](https://blastengine.jp/)はシンプルに使える開発者向けメールサービスを提供しています。何かと面倒なメール配信をシンプルに、かつ確実に送信先に届くようになります。

今回はblastengineを使ってPHPでメール送信を行うまでの流れを解説します。

## ユーザ登録する

blastengineにユーザ登録します。管理画面に入るためのユーザID、パスワードが手に入るので、ログインします（ユーザIDは後で使います）。

![getting-started-4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/515541ad-b74e-e1e2-ac34-46d181ee2924.jpeg)


## 送信元ドメインのSPFを設定する

送信元として利用するドメイン（自分で持っているもの）の設定をします。これは任意のドメイン管理サービスで設定できますが、TXTレコードに以下のSPFを追加します。

```
txt @ v=spf1 include:spf.besender.jp ~all
```

## API経由で配信する

まずはAPIを使ってHTMLメールを配信する流れを紹介します。

### APIキーを取得する

ログイン後、管理画面の右上にある設定メニューに移動します。

![getting-started-6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/47b2b2ac-2e41-77fe-d84f-0ae0b7541f36.jpeg)


そして設定の中で、APIキーを取得します。

![getting-started-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/2b5ca124-3020-1d39-84e4-911cd4db27e2.png)


### 必要な変数を取得

今回はターミナル（コマンドプロンプト）から実行します。その際にユーザIDとAPIキーを渡す仕組みにしますので、スクリプト側で入力値を受け取ります。また、両方とも必須なので、入力がなかったらエラーとします。

```php
$user_id = getenv("BE_USERID");
$api_key = getenv("BE_APIKEY");
if ($user_id === false) {
	echo "ユーザIDは必須です";
	exit;
}
if ($api_key === false) {
	echo "APIキーは必須です";
	exit;
}
```

### トークンを生成する

APIリクエストするためのトークンを生成します。手順としては次のとおりです。

1. ユーザIDとAPIキーを連結する
2. SHA256のハッシュを生成する
3. ハッシュを全て小文字にする
4. 3の文字列をBASE64エンコードする

実際のコードで言うと、次のようになります。 `$token` がトークンです。

```php
// トークン生成
$str = "$user_id$api_key";
$token = base64_encode(strtolower(hash('sha256', $str)));
```

### APIリクエストする

では実際にメールを送信します。APIのエンドポイントは `https://app.engn.jp/api/v1/deliveries/transaction` になります。生成したトークンは `Authorization` ヘッダーに適用します。fromのemailやtoなど、メールアドレスは利用されるものに書き換えてください。

```php
// APIエンドポイント
$url = 'https://app.engn.jp/api/v1/deliveries/transaction';
// POSTデータ
$data = [
	"from" => [
			"email" => "sample@example.jp",
			"name" => "送信者サンプル"
	],
	"to" => "to@example.com",
	"subject" => "テスト件名",
	"encode" => "ISO-2022-JP",
	"text_part" => "テスト配信",
	"html_part" => "<!DOCTYPE html><html><header></header><body>sample html</body></html>"
];
$data = json_encode($data);

// ヘッダー
$header = [
	"Content-Type: application/json",
	"Authorization: Bearer $token"
];
// リクエスト内容を組み立て
$context = [
	"http" => [
			"method"  => "POST",
			"header"  => implode("\r\n", $header),
			"content" => $data
	]
];
// APIリクエスト
$res = file_get_contents($url, false, stream_context_create($context));
```

### 結果

レスポンスを出力します。配信ID（delivery_id）は照会、変更および削除操作に必要です。

```php
echo $res;
// { delivery_id: 9 }
```

### 実行する

では実際にターミナル、またはコマンドプロンプトから実行してみます。 `YOUR_USER_ID` と `YOUR_API_KEY` はそれぞれ皆さんのものに置き換えてください。

```
$ BE_USERID=YOUR_USER_ID BE_APIKEY=YOUR_API_KEY php api.php
{ delivery_id: 9 }
```

### 全体のコード

今回のサンプルコードは次のようになります。実装時の参考にしてください。

```php
<?php
$user_id = getenv("BE_USERID");
$api_key = getenv("BE_APIKEY");
if ($user_id === false) {
	echo "ユーザIDは必須です";
	exit;
}
if ($api_key === false) {
	echo "APIキーは必須です";
	exit;
}
// トークン生成
$str = "$user_id$api_key";
$token = base64_encode(strtolower(hash('sha256', $str)));
// APIエンドポイント
$url = 'https://app.engn.jp/api/v1/deliveries/transaction';
// POSTデータ
$data = [
	"from" => [
			"email" => "sample@example.jp",
			"name" => "送信者サンプル"
	],
	"to" => "to@example.com",
	"subject" => "テスト件名",
	"encode" => "ISO-2022-JP",
	"text_part" => "テスト配信",
	"html_part" => "<!DOCTYPE html><html><header></header><body>sample html</body></html>"
];
$data = json_encode($data);

// ヘッダー
$header = [
	"Content-Type: application/json",
	"Authorization: Bearer $token"
];
// リクエスト内容を組み立て
$context = [
	"http" => [
			"method"  => "POST",
			"header"  => implode("\r\n", $header),
			"content" => $data
	]
];
// APIリクエスト
$res = file_get_contents($url, false, stream_context_create($context));
// 結果の出力
echo $res;
```

## SMTPリレーでの配信

次にSMTPリレーを使った方式です。

### IPアドレスの登録

SMTPリレーを利用する場合、まず接続元サーバのIPアドレスを管理画面で登録する必要があります。

![getting-started-6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/f2cf5673-9d25-24d9-5ae7-4c4469c6777e.jpeg)


IPアドレスの設定ダイアログで、接続元サーバのIPアドレスを入力してください。

![getting-started-7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/1f9612cb-55f1-237d-bd67-065688c7d802.jpeg)


### Postfixの編集

ネットで検索してよく出てくるphp.iniのSMTPサーバ設定はWindows向きの設定になります。恐らくLinuxサーバを利用するケースの方が多いが、php.iniの編集ではないので注意してください。Linuxの場合はPostfixを利用して配信します。この場合、`/etc/postfix/main.cf` を編集します。

下記1行を追加して保存します。blastengineのSMTPサーバアドレスは `smtp.engn.jp` 固定になります。ポート番号は25/587/2525より選択してください。

```
relayhost = smtp.engn.jp:587
```

Postfixが起動していない場合は起動してください。起動している場合には再起動が必要です。

```
$ sudo postfix start
// または
$ sudo postfix restart
```

### メール配信する

PHPで一番手軽に使えるメール配信用関数mb_send_mailを使います。mb_send_mailは配信完了するとtrue、失敗するとfalseを返します。

```php
<?php
// 宛先
$to = "sample@example.jp";
// 件名
$subject = "HTMLメール";
// HTML文
$message = "<html><body><h1>これはHTMLメールです</h1></body></html>";
// From
$headers = "From: from@example.com";
$headers .= "\r\n";
// HTMLメールの場合必要
$headers .= "Content-type: text/html; charset=UTF-8";
// 送信
mb_send_mail($to, $subject, $message, $headers); 
```

## まとめ

クラウドサービスではSMTPポートが塞がれている場合があるので、そうした時にはAPI経由を利用してください。SMTPリレーを使えば、より信頼性高く、安定した配信が実現できるでしょう。

APIとSMTPリレー、それぞれの要件に合わせて最適な方を選択してください。

[エンジニア向けメール配信システム「ブラストエンジン」](https://blastengine.jp/)