14
16

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 5 years have passed since last update.

JX通信社Advent Calendar 2018

Day 3

Slack チャンネルごとにメールを受け取れるようにした話

Last updated at Posted at 2018-12-02

:christmas_tree: k この記事は JX通信社 Advent Calendar 2018 の 3 日目の記事です。


Slack のメール連携を便利にしてみた話。

image.png

皆さん、Slack のメール連携って利用されていますか?
Slack 公式のプラグインでメールを直接チャンネルで受け取ることができるようになっています。
外部との連絡も Slack で完結し、受信者だけでなくチームにも内容を共有できるので便利ですよね。

ただ、このプラグインによる連携、運用しているといくつか手の届かないところがあります。

  • タップしないと詳細がわからない
  • 1 チャンネルごとにメアドを生成しないといけない
  • メンション飛ばしたりなどのカスタムができない

具体的にはこのあたりですね。
特に日本語のメールはタイトルだけでは内容が分からないものが多いので、タップしないと詳細が読めないというのは不便です。

そこで自作のメール連携を作って便利に使おう!というのが今回の趣旨になります。

作ったメールサービス

最初に完成形から。

image.png
こんなメールを今回作成したシステムのメール宛に飛ばすと、以下のような感じで Slack に届きます。
image.png

Slack 上でのフォーマットの仕方についてはまだ改善の余地がありそうですが、Python で本文が取れる状態になっているので、変えたい人に変えてもらうというスタンスです。#WelcomeContribution
カスタマイズの方向性としては、送信元に応じて表示フォーマットを変えたりだとか、特定のキーワードでメンション飛ばしたりだとかいろいろできそうです。

任意チャンネルへ送信

このシステムもう一つ仕掛けがあって、なんと任意のSlackチャンネルにメールを送れます。

{チャンネル名}@{メールのドメイン}

というメールアドレスに向けてメールを送るだけです。

仮にドメインを channel.example.com とするなら、

  • general@channel.example.com#general チャンネルに
  • test@channel.example.com#test チャンネルに

といった使い方ができます。
ドメインを覚えてしまえば、もういちいちメアドを発行する必要はありません。

image.png

一つ問題があるとすれば、日本語チャンネルには RFC 5321 の規約上送れないということですね…。
Base64などでエンコードしてしまう手はありますが、エンジニア以外だと利用するのが難しくなってしまいそう。

サーバレスなメールシステム

続いて、メール連携のシステムについて紹介していきます。

image.png
このメールシステムは AWS を利用して、1サーバレスな構成で実現しています。

SES(Simple Email Service) というサービスを利用すると、メールの受信から AWS 内の他サービスへの受け渡しまでをまるごと面倒見てくれます。
メールサーバーの構築や運用は自分でやろうとするとかなり大変ですが、こうやってサービスとして提供されているとありがたいですね。
受け取ったメールをS3 へ保存し、同時にメールを処理するための Lambda を発火させてあげます。

def lambda_handler(event, context):
    for mail in event['Records']:
        if 'ses' not in mail:
            continue
        mail = mail['ses']['mail']

Lambda ではイベントという形でデータが (ときには複数まとめて) 送られてくるので、上記のように SES のメール情報を取り出してあげます。

        obj_id = mail['messageId']
        obj = bucket.Object(f'{obj_id}')
        raw_mail = obj.get()['Body'].read()

このメール情報にはメール本文自体は含まれないので、別途 S3 に保存したデータを messageId から持ってきてあげる必要があります。

これで Slack に送るのに必要な情報が揃いましたね。
あとは煮るなり焼くなり好きにいじって Slack に送るだけです。

https://gist.github.com/pistatium/defe9cd71a9d0487b92d922f871ddbfa
Slack への送信等は改めて説明するほどでもないので、こちらにサンプルのソースを置いておきます。
メールの生データを処理するのが結構鬼門ですが、一応 Python の標準ライブラリで処理することが可能です。
サンプルだと HTML タグはすべて外してしまってますが、うまくやれば Slack 表記に変換してあげるとかもできそうです。

  1. <宣伝>サーバレスについては (私を含め) 弊社エンジニアが執筆した[こちらの特集](https://gihyo.jp/magazine/wdpress/archive/2018/vol105)が参考になるかもしれません。宣伝>

14
16
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
14
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?