はじめに
どの会社でも業務上の申請フローがあると思いますが、そういった業務フローを整備している途中のベンチャーでは様々なフローが整っていないことがよくあります。
scouty でも少し前までは何か購買を依頼する時には 申請用の slack チャンネルに書き込んで、それを担当者が見て処理する というやり方をしていました。
社員数が少ないうちはこのような slack だけのフローでも問題なく回せると思います。
ところが最近、弊社バックオフィス担当の業務負荷が一時的に非常に高くなり明らかに大変そうにしており、そんな時に slack でのこの発言をみて 「これを運用し続けるのはどう考えても無理がある・・・!!!」 と思いました。
抱えていた課題
これまでに行われていた slack だけでの申請フローだとざっくりとこんなところが困っていたと思います。
- 申請を処理する人たち
- 申請が来ても気づかず見落としてしまう場合がある
- 申請する人たち
- 自分が出した申請の対応状況が担当者に聞かないと分からない
こういう日々発生する 細かいところでいちいち気にしたり都度考える必要があると、ちょっとずつジワジワと頭のリソースが消費されてしまい 本来やるべき本質的なことではないのに非常にもったいないですよね。
そこで、なるべくシンプルかつ今まで触ったことがない技術を使って上記の課題を解決する仕組みを作れば、 みんな助かるし自分としてもアドベントカレンダーのネタができてみんなが幸せになっている未来しか見えない! と思って購買申請フローを簡単にする仕組みを作ることにしました。
作ったもの
以下のような仕組みを作りました。
- Google フォームから購買申請を入力
- 申請内容を GitHub issue として自動作成
- 申請が登録・クローズされると処理担当者と申請者に slack で通知
申請者、担当者それぞれが微妙に困っていたところを解決する仕組みになっています。
仕組みの中身
Simple & Easy 購買申請フロー は以下を使って実装されています。
(くそダサいけどここではそう呼びます)
- Googleフォーム
- Gapps Script
- Firebase (Cloud Functions)
- GitHub issues
- Slack
Firebase が中心となってそれぞれと連携しています。
コード
公開用にすこしいじったコードを GitHub で公開しています。
特に特殊なことはありませんが、似たような仕組みを作りたい方がいたら参考になれば嬉しいです。
https://github.com/Chanmoro/easy-workflow
今回 Firebase の cloud functions を初めて使いましたが、node.js で express を使って web アプリを作っているのと同じなので、コードで困ったところは特になかったです。
ハマった点
firebase から外部に通信できない
無料登録をした直後の課金が発生しないプランだと firebase の Cloud Functions から外部に通信できない制限がかかっていました。
クレジットカードの情報を登録して従量課金プランにするとこの制限が外れます。
無料枠の範囲があり 12万リクエスト/月までは無料で使えるので今回の用途では無料枠の範囲でまかなえると思います。
Gapps Script ではリクエストヘッダーにアクセスできない
当初はなるべく簡単にしたかったので Gapps Script だけで作ろうとしており、GitHub の webhook を受け取るのも Gapps Script でやろうとしていました。
セキュリティを強固にするために webhook で設定できる secret token を使った署名のチェックを実装しようとしたのですが、Gapps Script ではリクエストヘッダーにアクセスできないことが分かりこの対応はできませんでした。
リクエストパラメータに認証トークン的なものをつけた URL を webhook に設定するなど、自前で簡易的に認証を入れるようにすれば Gapps Script だけでも実現できると思います。
今回はアドベントカレンダー用のネタを確保するという目的も途中でプラスして、ついでに typescript にも入門したと思い firebase を使うことにしました。
こういうのを動かすのは heroku とかでもいいんですが firebase の格安さは非常に魅力だと思います。
初回のリクエストには起動に時間がかかる
cloud functions はコールドスタートなので、デプロイの直後やしばらく時間が経つと処理に時間がかかります。
恐らくコンテナが停止している場合の起動に時間がかかっていると思われます。
今回のケースでは手を抜いて1つの function を通常の express アプリケーションのように実装してしまいましたが、なるべくURL単位でアプリケーションを細かく分けて起動にかかる処理をコンパクトにしておく方が良さそうです。
最後に
この記事では、 既存の購買申請フローにあったちょっとした課題を便利な技術で解決しました 、ということを書きました。
もちろんこれが完璧な仕組みではないことは重々承知していますが、こういうちょっとした工夫で日々ちょっとだけ困っていることを解決できるのはエンジニアとしてとても楽しいことですよねー。
影響の小さいところでいろいろと試してみると、 エンジニアリングでの課題解決の楽しさも新しい技術の習得もどちらも得られて非常にお得 だと思うので、これからもちょこちょこやっていこうと思います!