見出し画像

メールを効率よく処理していくための仕組みを作りました

Tably でソフトウェアエンジニアをしている、よういちろう(@yoichiro)です。

今年の初めに Tably に入社してから今日に至るまでに、かなりの方々から「よういちろうさんって、今なにやってるんですか?」というご質問を多くいただきました。興味を持っていただいてとても嬉しいのですが、今まで「こんなことしてます」と紹介する機会もあまりありませんでした。

そこで今回は、入社後にいろいろ作ってきた中で「実はこんなものを作ってました」ということを、ひとつ紹介してみたいと思います。他のものはまだナイショですが、良きタイミングでお伝えしていければと思います。

日頃メールをどれだけ送受信してますか?

多くの方々がパソコンを毎日使って仕事を行うようになってかなりの年月が経ちましたが、「メール」を誰かと送受信する機会を皆さんどれほどお持ちでしょうか?

僕はというと・・・1日の間でメールを読む機会は数回しかなく、メールを書く頻度もかなり低い状況です。代わりに Slack や Twitter など他の手段でコミュニケーションを行う時間がとても長くなりました。ソフトウェアエンジニアの方々であれば、僕と同じ状況の方々が多いのではないか、と想像します。

しかし、周りに目を向けてみると、メールはまだまだコミュニケーションの中心です。

メールの受信は業務のきっかけである

請求書や見積書などは、メールで送りあうことが多いでしょう。弊社が手がけている研修事業では、課題をメールに添付して提出していただくことがほとんどです。また、企業ごとに「お問い合わせはこのメールアドレスまで」と問い合わせ窓口をメールにしていることも多く、初対面の相手に対してコンタクトを取るための手段としても、メールは活用されています。

特に、近年では「何らかのファイルを相手に届けるための手段」としてメールを活用している場面が多いかと思います。例えば、毎月メールで送られてくる領収書は、相手側のサービスから自動的に送信されてくるものであり、いちいちその相手に返事を書くことはありません。そして、そのメールの本文はどうでもよく、むしろ添付されてくる PDF ファイルの方が重要です。

つまり、メールを受け取った後、読んで返信する以外にも、今日では以下のようなことが行われています。

・ 添付ファイルとして送られてきた請求書や領収書などのファイルを、Google ドライブやファイルサーバの所定の場所に保存する。
・ メールの本文に領収や請求などの内容が書かれていた場合は、本文を PDF ファイルとして出力して、同じく Google ドライブやファイルサーバの所定の場所に保存する。
・ 問い合わせ先メールアドレスに送信されたメールの内容を、Trello や問い合わせ管理システムに転記して登録する。
・ 受け取ったメールに zip ファイルが添付されていて、次にパスワードが書かれたメールが送信されてきた際には、zip ファイルを手元に保存し、次に来たメールからパスワードをコピーして zip ファイルの展開時に入力して、結果得られたファイルに対してファイルサーバにアップロードするなどのことを行う。
・ 上記を行ったことを、Slack などでチームメンバーにシェアする。

それって人間のやることですか?

企業の大小に関わらず、上記のようなメールに対する業務は、誰かが行っていることと思います。取引先が多ければ多いほど、経済活動がアクティブであればあるほど、メールの量は多くなり、その結果、上記のような関連して行わなければならないことが増えます。月末に近くなれば、それだけで一日が過ぎていきそうです。

でも、上記のようなことって、本当に人間がやるべきことでしょうか?

ほとんどの場合、やることはパターン化されます。請求書などが送られてくる先は、ある決まったメールアドレス宛でしょうし、問い合わせなどについても同様です。添付ファイルがなくても、経理関連宛に送られたメールであればその本文には重要なことが書かれているでしょうから、PDF ファイルとして出力して保管しておけば間違いはないでしょう。Trello カードの作成や Slack での周知も、同じような作業の繰り返しです。

そして、パスワード付き zip ファイルのメールとは別にパスワードが書かれたメールを送ってくるケースこそ、メールの受信者に手間をかけさせるだけの「ひどい業務」であり、PPAP 問題として有名です。おそらく送信する側は特別な SMTP サーバが自動的にパスワード付き zip ファイルの生成とパスワード記載メールの送信をやっているので手間は全くかかっていないはずで、受け手にコストを支払わせています。

これらのことは、全部自動化してしまえば良いのです。そう、作っちゃえば良いのです。

画像1

図1. Email Flow を構想していたときのアイディアを図に書いたもの

メールを受信してからゴニョゴニョすることができるツールやサービスは、すでにいくつかあります。例えば、Microsoft Power Automate(旧 Microsoft Flow)や Zapier などが代表例でしょう。最初はこれらを使って実現しようかな、と思っていましたが、以下のような懸念点がありました。

・ 既存サービスは、どれも自由にカスタマイズして「かゆいところに手が届く」ようには見えなかった。そして、特定のサービスの使い方をディープに学習する気にはなぜか僕はならなかった。
・ 初期開発コスト(= 僕の手を動かすこと)を払うよりも、かゆいところに手が届かなそうなツールに費用を支払い続けたくはなかった。
・ 弊社の研修事業はコア業務であり、何ら妥協せずに全てが手の内の状態で、コア事業の効率化を実現できる状態にしておきたかった。
・ 僕が一人でゼロから作っても1ヶ月もかからずにシステムは動き始められるだろうという自信があった。
・ 既存サービスではどうしても実現できないことがあった(例: パスワード付き zip ファイルの自動展開)。
・ 何よりもこれは「自分への挑戦状」だと思った(え、作れないの?とは言わせない!)。

最後の点は余計ですが、そんなこんなで自作することに決めました。

そこで作ってみました「Email Flow」

弊社において、今では「上記で取り上げたユースケース全てを自動化することが可能なシステム」が稼働しています。その名は、「Email Flow」です。

元々、メールで送られてきた請求書の添付ファイルを Google ドライブに自動アップロードすることを目的に開発したのですが、弊社が手がけている研修事業での課題の提出への対応なども見据えて、ワークフローを汎用的に組立可能とすべく、一度設計し直した結果現在稼働しているシステムが、Email Flow となります。

Email Flow は、受信したメールに対して、○○という条件(Condition)を満たした場合は△△をする(Worker)、というルールを定義することができます。

画像2

図2. ルール定義の構造

現在サポートしている仕様としては、以下が挙げられます。

条件指定(Condition)
・ From, To, CC に対する完全一致、正規表現、一覧からの一致
・ 添付ファイルの存在有無
・ Worker の実行結果に対する一致
できること(Worker)
・ メール本文の加工(本文の前後に指定文字列を追加)
・ メール本文の PDF ファイル出力
・ zip ファイルの自動展開(パスワード付き zip ファイルも対応)
・ Google ドライブへのアップロード
・ Trello カードの自動作成
・ Slack へのメッセージ送信

これらを任意の組み合わせや順番で処理することが可能です。

画像5

図3. Email Flow はメールを様々に自動処理する

例として、弊社では以下のような組み合わせでワークフローを運用しています(一部実際の設定とは異なります)。

経理関連メール(添付ファイルあり)
[Condition]
・ to: accounting@tably.co.jp
・ 添付ファイルあり
[Worker]
1. Google ドライブへの添付ファイルアップロード
2. Slack へのメッセージ送信
経理関連メール(添付ファイルなし)
[Condition]
・ to: accounting@tably.co.jp
・ from: 特定のメールアドレス数個
・ 添付ファイルなし
[Worker]
1. メール本文の PDF ファイル出力
2. Google ドライブへの添付ファイルアップロード
3. Slack へのメッセージ送信
問い合わせ関連メール
[Condition]
・ to: inquiry@tably.co.jp
[Worker]
1. メール本文の冒頭に特定の文を追加
2. Trello カードの自動作成
研修課題メール
[Condition]
・ to: homework@tably.co.jp
・ 添付ファイルあり
[Worker]
1. Google ドライブへのファイルアップロード
2. zip ファイルの自動展開(パスワード付きの場合はログ出力)- (1)
3. Slack へのメッセージ送信
研修課題メール(パスワード付き zip ファイル展開)
[Condition]
・ Worker (1) のログがあること
・ from: Worker (1) のログに書かれた from と一致
[Worker]
1. メール本文からパスワード文字列候補を抽出して zip ファイル展開
2. Slack へのメッセージ送信

実際にはもっと細かく条件指定や Google ドライブのアップロード先ディレクトリの指定などいろいろできるのですが、ざっとできることを並べると、上記のような感じです。このような処理であれば、人間が何もしなくても、Email Flow が全部やってくれます。

画像3

図4. Slack に通知されたメッセージの例

仕組みは?

Email Flow は、Google Cloud Platform が提供する以下のサービスを組み合わせて実現しています。

・ Google AppEngine
・ Cloud Functions
・ Cloud Pubsub
・ Cloud Datastore
・ Cloud Storage

GAE には、メールを受信する機能があるので、それを入り口としています。データベースとして Cloud Datastore を採用し、ルールの設定内容や、実行されるワークフローの状態管理を行っています。受信したメールの内容や添付ファイルの一時格納場所として Cloud Storage を使っています。

受信したメールの条件判定や、各種 Worker は、全て「Cloud Functions と Cloud Pubsub の組み合わせ」として実装されています。email-flow-worker-manager という名前の Worker が仲介者となり、次に実行すべき Worker が持つ Topic にメッセージを送信することで、処理の依頼を行います。処理が完了したその Worker は、email-flow-worker-manager に完了をやはり Topic 経由で通知し、次の Worker の Topic にメッセージ送信されて次の処理が行われる、という連鎖となります。

画像4

図5. アーキテクチャ

大きな一つの Cloud Functions として作ってしまうのではなく、Worker をそれぞれ別の Cloud Functions + Cloud Pubsub として実装することで、柔軟性を確保しています。特に「Condition と Worker の動的な組み合わせ」によって、パスワード付き zip ファイルの自動展開といった「2通のメールで一つのワークフロー」という比較的難易度の高い処理も対応することが可能となりました。

現時点の課題とまとめ

すでに弊社内では Email Flow によるメールの自動処理が行われ、なくてはならないシステムとなっています。今後も「人間がすべきことではないことは自動化する」ために、Email Flow に手を入れていくことになりそうです。

機能追加が柔軟に可能になっている反面、それら機能を組み合わせてワークフローとするためのルールの設定が、現状では「RDBMS に SQL の INSERT 文で直接突っ込む」方式になってしまっていることが、最大の課題かもしれません。これは柔軟性と利便性のトレードオフであり、現状は前者に振り切っています。今後時間を見つけて、後者にも取り組もうかな、と目論んでいます。

今回は、僕が弊社にてやっていることの一部を紹介してみました。今後も自身が持っている技術とアイディアを活かして、いろいろと生み出していく所存です。

最後に、弊社バックオフィス担当からの声を掲載して、終わりといたします。

” 添付ファイルのGoogleドライブ自動格納によって、月次の経理作業が格段に楽になりました:) また問い合わせの自動Trelloカード化は、地道なコピペ作業がなくなりすぐに議論に入れるのでとても助かっています!日々の業務に追われているとついつい作業を優先し自動化を後回しにしてしまいがちですが、ちゃんとヒアリングして自動化の仕組みを作ってくれるのは素晴らしいなと思いました。そんなエンジニアさんがいると、世のバックオフィスの方々はだいぶ救われるのではないかと思います。”