MailHogでメール送受信のテストをする

### インストールと実行

MailHogはGo言語でできているので、[release用にビルドされたバイナリ](https://github.com/mailhog/MailHog/releases)を落として実行するだけで使えます。

```bash
$ wget https://github.com/mailhog/MailHog/releases/download/v0.2.1/MailHog_linux_amd64
$ chmod +x MailHog_linux_amd64
$ ./MailHog_linux_amd64
```

デフォルトの挙動ではメールはメモリ上に保存されるので、プロセスを停止させると受信したメールは消えます。
その場合はsliceでデータを保持しているので、大量にメールを送る試験をする場合はあまりメモリ効率が良くないかもしれないので注意が必要です。

SMTPは1025ポートで待ち受けています。

#### 基本的な使い方

ブラウザに http://localhost:8025/ にアクセスするとWeb UIが表示され基本的にはそこで操作します。
下図はメールを2件受信している場合の例です。
![Mailhog.png](https://qiita-image-store.s3.amazonaws.com/0/17814/a63ed0bb-712b-68ac-9266-26844a0ee1b0.png)

https://github.com/mailhog/MailHog/issues/126 にあるようにHTMLメールだと表示が崩れることもあるようです。

#### 起動オプション

ポート番号などを変更したい場合は、以下のように起動オプションをつければ変更できます。
何が変更できるかはhttps://github.com/mailhog/MailHog/blob/master/docs/CONFIG.md  で確認できます。

```bash
# webの待ち受けポート番号を変えてみる
$ ./MailHog_linux_amd64 -ui-bind-addr 0.0.0.0:8026
```

#### PHPから使う

以下のように、php.iniのsendmail_pathでMailHogを利用するように指定するだけです。

```php.ini
sendmail_path = "/usr/local/sbin/MailHog sendmail test@example.org"
```

### APIでの操作

Web画面をこ萎える操作は[V2 API](https://github.com/mailhog/MailHog/blob/master/docs/APIv2/swagger-2.0.json)でも、操作可能です。([V1 API](https://github.com/mailhog/MailHog/blob/master/docs/APIv1.md)もあります）

#### メール一覧を取得

APIでメール一覧を取得する場合は以下のようにします。
全体の何件目から取得するか（start）と、1回に何件取得するか（limit）が指定できます。
limitは最大で250まで指定可能です。

```bash 
$ curl http://127.0.0.1:8025/api/v2/messages
[APIv2] GET /api/v2/messages
{"total":0,"count":0,"start":0,"items":[]
 
# メールのSubjectはMIMEエンコードされた文字列が返ってきます
$ curl http://127.0.0.1:8025/api/v2/messages|jq  '.items[].Content.Headers.Subject'
[
  "=?UTF-8?Q?[Welcome_to_the_VCCW=E3=82=B5=E3=82=A4=E3=83=882]?= =?UTF-8?Q?_=E3=83=91=E3=82=B9=E3=83=AF=E3=83=BC=E3=83=89=E3=81=AE=E3=83=AA=E3=82=BB=E3=83=83=E3=83=88?="
]
 
# nkfとかでMIMEデコードすると日本語が含まれたメールも表示することができます
$ curl http://127.0.0.1:8025/api/v2/messages|jq  '.items[].Content.Headers.Subject'| nkf -w
[
  "[Welcome to the VCCWサイト2] パスワードのリセット"
]
 
# 複数件のメールから先頭のものを取得したい場合は普通にheadとかでパイプで処理できます
$ curl http://127.0.0.1:8025/api/v2/messages|jq  '.items[].Content.Headers.Subject[0]'| head -1|nkf -w
"[Welcome to the VCCWサイト2] パスワードのリセット"
$ curl http://127.0.0.1:8025/api/v2/messages|jq  '.items[].Content.Headers.Subject[0]'| nkf -w
"[Welcome to the VCCWサイト2] パスワードのリセット"
"[Welcome to the VCCWサイト2] パスワードのリセット"
 
# メールのBodyを確認するときは以下のようにすると確認できます。
$ curl http://127.0.0.1:8025/api/v2/messages|jq  '.items[].Content.Body'|sed -e 's/\\r\\n//g' -e 's/"//g'|base64 -d
だれかが次のアカウントのパスワードリセットをリクエストしました:
 
http://vccw.dev/
 
ユーザー名: admin
 
もしこれが間違いだった場合は、このメールを無視すれば何も起こりません。
 
パスワードをリセットするには、以下へアクセスしてください。
 
<http://vccw.dev/wp-login.php?action=rp&key=8ZwuS1aVSLRf5CdyH1H5&login=admin>
```

#### 特定のメールを取得

V2 APIでは以下のようにFromや、Toなどから取得するメールを絞ることが可能です。

```bash 
# v2のsearch APIで絞れるがそれほど情報は絞れない。
# kind は from,to,contain が指定出来、query は、文字列が指定できる（startとlimitはmessagesと同様）
$ curl -X GET http://127.0.0.1:8025/api/v2/search?kind=to\&query=vccw@example.com
```

ただし特定のメールを1件だけ取得する場合は、以下のようにV1 APIを利用します。

```bash
# メッセージ一覧を取得して、IDを取得します
$ curl http://127.0.0.1:8025/api/v2/messages|jq  '.items[].ID'
"keFzNk-8oxjhwPgHb6P2Fb-X-wKmPVMxgJDOKg-3KPo=@mailhog.example"
# 上記で確認したIDで特定のmessageを取得します
$ curl http://127.0.0.1:8025/api/v1/messages/keFzNk-8oxjhwPgHb6P2Fb-X-wKmPVMxgJDOKg-3KPo=@mailhog.example | jq
# 結果は省略
```

#### メールの削除

V1 APIを利用して以下のようにメールを削除します。

```bash
# 削除はこんな感じです
curl -X DELETE http://127.0.0.1:8025/api/v1/messages/keFzNk-8oxjhwPgHb6P2Fb-X-wKmPVMxgJDOKg-3KPo=@mailhog.example
```