Slack による荷物配達・受け取りの効率化について

この記事は、Slack を使って Amazon のコンビニ受け取りや、佐川急便の荷物受け取りを効率化する方法について説明しています。

# TL;DR

- Amazon のコンビニ受け取り、荷物配達を Slack へ通知すると便利
- クロネコヤマト、佐川急便の不在通知はメールで受け取ることができる
- [Mailgun](https://www.mailgun.com/) を使うと、メール駆動な Web アプリケーションが容易に作成可能
 
## 例
![](https://qiita-image-store.s3.amazonaws.com/0/51394/5e43280d-379c-1bd7-b6ab-e3204d104124.png)

# Slack とは
言わずと知れたチャットサービスです。

[![Slack](https://qiita-image-store.s3.amazonaws.com/0/51394/ea2507eb-4d16-6a10-a3d0-69731c40ee84.png)](https://slack.com/)

# どんな問題を解決したいか
日頃 Slack を使っている皆さんは、様々な通知を Slack に集約して快適な生活を行っていることだと思います。この記事では、その中でも以下のような 『 荷物受け取り 』 に関する問題を解決する方法を説明しています。

- Amazon のコンビニ受け取りの際、コンビニに到着したことを気づけない
  - 新刊の発売日など、なるべく早く到着を知りたい
- 佐川急便やクロネコヤマトの不在通知をすぐに知りたい
  - 日中に不在通知を知って、夜に受け取りたい

これらの問題を、Slack を使って **リアルタイム** に通知を送ることにより解決したいと思います。

# どうやって荷物のコンビニへの到着や、不在通知を知るか
コンビニ受け取りの際のコンビニへの到着や、不在通知を (ポストへの投函などではなく) IT 的な方法で知るには、メールを用いるのが便利です。

## Amazon のコンビニ受け取りの到着通知
これは、何もせずとも普通に Amazon から送られてきていると思います。このメールが到着した際に、通知を発火すれば OK です。

![コンビニ受け取りの到着メール](https://qiita-image-store.s3.amazonaws.com/0/51394/a591c72a-5f9e-9bf8-2f16-377ecf0440c7.png)

## 佐川急便の不在通知
佐川急便の [WEB トータルサポート](http://www.sagawa-exp.co.jp/service/wts/) というサービスを利用することにより、不在通知をメールで受け取ることができます。事前に [会員登録](https://www.e-service.sagawa-exp.co.jp/portal/do/login/logout) 及び、メール自動配信設定が必要です。

登録すると、以下の様なメールを受け取ることができます。

![佐川急便の不在通知メール](https://qiita-image-store.s3.amazonaws.com/0/51394/6b38a811-6b82-3bdd-ed87-3da1d2cf6bb6.png)

## クロネコヤマトの不在通知
[クロネコメンバーズ](https://cmypage.kuronekoyamato.co.jp/portal/entrance) に登録することにより、不在通知をメールで受け取ることができます。事前に会員登録及びメール配信設定が必要です。

登録すると、以下の様なメールを受け取ることができます。

![クロネコヤマトの不在通知メール](https://qiita-image-store.s3.amazonaws.com/0/51394/c71cad64-0861-a790-194e-9c2e0177ca49.png)

# メール通知を受信して Slack へ通知するには
Amazon のコンビニ受け取りなどの通知メールを Slack に通知するには、メール受信のイベントにより Slack に通知する処理を呼び出す必要があります。

定期的に Gmail の API (や IMAP) を叩いてポーリングし実現することもできますが、それの方法はなんともイケてないので、メール受信をイベントとしてリアルタイムに Slack に通知する処理を発火する手法を用います。

今回は、[Mailgun](https://www.mailgun.com/) というサービスを利用し Gmail へ届いたメールを Web アプリケーションでリアルタイムに処理する手法を紹介します。

![](https://qiita-image-store.s3.amazonaws.com/0/51394/6a419905-6fb4-9ee9-4f22-41a5428b7bae.png)

## [Mailgun](http://www.mailgun.com/) とは?

![Mailgu](https://qiita-image-store.s3.amazonaws.com/0/51394/cc003e5b-6700-4f74-4221-e2ecbdd1973f.png)

Mailgun はメールの送受信を行ってくれるクラウドサービスです。Mailgun を使うためには、自分のドメインに Mailgun のメールサーバーの MX レコードと、SPF と DKIM の TXT レコードを設定する必要があります。そうするより、メールの送受信を Mailgun の API 経由で行えるようになります。

メールサーバー関係の DNS の設定は、実際に Mailgun に登録してみるとわかると思いますが、親切丁寧に順を追って説明されるので、特に迷わず利用できると思います (設定がうまくいってないと、その箇所を教えてくれます)。

気になる [価格](http://www.mailgun.com/pricing) は、Mailgun では月 1 万通までは無料枠が設定されているので、個人で使う場合は実質無料で利用できます。

## Mailgun へメールを転送する設定について
Mailgun を用いて、メール受信をイベントドリブンで処理を行うには、下記の 2 箇所で設定が必要です。

1. 利用しているメールサービス (ex. Gmail) から Mailgun への転送
2. Mailgun からメールを処理する Web アプリケーションへの転送

1 は、何らかの手法で処理したいメールを Mailgun へ転送すれば OK です。Gmail を利用している場合、フィルタを使って特定のメールのみを転送するか、全メールを転送する設定をするかします。

2 は Mailgun で [Routes](https://mailgun.com/cp/routes) の設定を行います。Mailgun を経由して、全てのメールを Web アプリケーションへ転送する場合、以下の様な設定になります。

![Mailgun: Routes](https://qiita-image-store.s3.amazonaws.com/0/51394/3ae2955a-0a92-299e-5ebc-80de0fc5615d.png)

## Mailgun から発生する WebHook の処理について
Mailgun の Routes で forward されたメールは、WebHook として処理できます。WebHook には、以下の様なデータが付加されています。

![](https://qiita-image-store.s3.amazonaws.com/0/51394/18cce931-29f2-42fe-698c-36f1e0f92591.png)

WebHook からは、メッセージのタイトルや内容、メールヘッダの情報を取得できるので、メールの情報を使い柔軟に処理が可能です。あとは、お好きな言語とフレームワークを使って、ご自由にメッセージを処理してください。

WebHook から渡ってくる詳しい情報は、公式ドキュメントの [Receiving, Forwarding and Storing Messages](https://documentation.mailgun.com/user_manual.html#receiving-forwarding-and-storing-messages) の項目をご覧ください。

## Mailgun から受信したメッセージの検証について
Mailgun の WebHook 先を Web アプリケーションとして公開するということは、誰しもが自由に WebHook にアクセスできるということになります。それでは困るので、Mailgun の WebHook では渡ってきたメッセージ内容の検証が行えるようになっています。

WebHook のデータには、HMAC-SHA256 を用いたデータの改竄検証用の token と signature が付与されています。

以下は、私が個人用途のため開発して利用しているメール通知 bot の、メッセージ検証コードの一部です (Perl 5)。全てのコードは、諸事情 [^1] により公開できません…。

```pl:Mailgun.pm
# メッセージの署名を検証する
sub verify {
    state $v = Data::Validator->new(
        message   => 'Est::Model::Message', # 内部モデルへ変換したメッセージ
        timestamp => 'Str',
        token     => 'Str',
        signature => 'Str',
    )->with(qw/Method/);
    my ($class, $args) = $v->validate(@_);
    
    # 検証処理
    my $api_key   = Est::Config::Mailgun->param('api_key');
    my $timestamp = $args->{timestamp};
    my $token     = $args->{token};
    my $signature = $args->{signature};
    my $data      = $timestamp . $token; # 署名するデータ
    my $verified  = $signature eq hmac_sha256_hex($data, $api_key); # HMAC-SHA256 で検証 !!
    
    # 検証結果をロギング
    Est::Model::MailgunVerifyLog->logging(
        subject   => $args->{message}->subject,
        timestamp => $args->{timestamp},
        token     => $args->{token},
        signature => $args->{signature},
        verified  => $verified,
    );

    # 検証に失敗したら死ぬ
    Est::Service::Mailgun::Exception::VerifyFailedException->throw unless $verified;
}
```

# 結論

- Amazon のコンビニ受け取り、荷物配達を Slack へ通知すると便利
- クロネコヤマト、佐川急便の不在通知はメールで受け取ることができる
- [Mailgun](https://www.mailgun.com/) を使うと、メール駆動な Web アプリケーションが容易に作成可能

[^1]: テストコードに実際の過去のメールを用いてたり、個人的なメールが条件が含まれていたりするため、Private Repository です。