感謝、称賛メッセージを送るSlackアプリを作ってみた | Dev Driven 開発・デザインチーム 感謝、称賛メッセージを送るSlackアプリを作ってみた | 働くひとと組織の健康を創る iCARE

BLOG

感謝、称賛メッセージを送るSlackアプリを作ってみた

安田俊之
2019/06/13

エンジニアの安田です。

今日は弊社が社内カルチャーを育てるために作成したSlackアプリについてお話します。

Engazifyロス

弊社では1ヶ月ほど前まで
Engazify
というSlackアプリを使っていました。

このサービスを利用してみての感想は
感謝、称賛のメッセージを送るということ
に書いたことがあります。

このEngazify、サービスそのものはとても良かったのですが、安定性に欠けていて、1ヶ月ほど前辺りからサービスそのもののレスポンスがなくなってしまいました。
とはいえ、メンバー同士で称賛しあうこのアプリがないのは、非常に寂しく社内でも代替サービスを求める声が上がっていました。
ところが、なかなか代替サービスで良いもの、かつリーズナブルのものが見つかないので、腹を決めて自前で作成することにしました。

Slackアプリの技術選定

Slackアプリを作るにあたって、仕様に関しては上記のEngazifyを使う中でどういう機能がほしいかは固まっていたので、実際の作業としては、インフラを何にするか?プログラミング言語を何にするか?の検討からはじめました。

今回のSlackアプリの要件としては、

  • さしあたり巨大なシステムを作るわけではない
  • 通常業務とは別に作業するので、スピーディに開発できる環境が望ましい
  • Slackからのリクエスト(Slack上で発生したイベント情報)を常時受け付けられる環境である必要がある
  • リーズナブルでないとCXOに文句を言われる(と思われる)
  • とはいえ社内のコミュニケーションをさばくのでセキュアである(SSLプロトコルでやり取りする)必要がある

といった点がありますので、まず、これらを満たせるインフラとして

  1. AWS Lambda
  2. HEROKU
  3. Amazon EKS
  4. AWS Elastic Beanstalk

といった候補を上げてみました。

  1. AWS Lambdaについては、RDSのようなDBにデータを保持する場合の相性が悪いという話がネット上で散見される
    LambdaとRDSで爆死してみる
    Lambda+RDSはアンチパターン
    ので、除外
  2. HEROKUも無料プランだとスリープしてしまい、レスポンスを受け付けられなくなるので試用しずらい。また弊社サービスはAWS上で展開されており、新たにHerokuのエコシステムに慣れるのが面倒くさい、といった理由で除外
  3. Amazon EKSは弊社HPですでに利用しており、これを利用することで、EKSおよびKubernetesの知見をさらに深めたかったのですが、適当なHelm Chartが見つからず、いちいちkubectl(Kubernetesのリソースを操作するコマンド)で環境を構築したり、自前でHelm Chartを作ったりするのはさすがに時間がかかるので除外

ということで4. Elastic Beanstalkは使ったことはなかったのですが、簡単らしいということは知っていたので、これを使うことにしました。

もう一つ検討しなければならなかったのがプログラム言語。

候補として

  1. Javascript
  2. Python
  3. Ruby

を考えました。

  1. Javascriptは、Slackアプリに関する情報もネット上にたくさんあり、有望に思えたのですが、DB保存周りのORマッパーを書くことを考えると、RubyOnRailsの方が楽だな、という印象を受けたので不採用
  2. Pythonは、今後このSlackアプリにAIを搭載することとか将来性考えると有望に見えたのですが、スピーディにシステム構築をしたいことを考えると、経験の浅いPythonで書くのは、不適当と思われ、これも不採用
    ということで3. Ruby。業務内でも普段から書き慣れているRuby、RubyOnRailsで書くことにしました。APIなのでSinatraのような軽量なフレームワークのほうが良いかもしれませんが、Railsは弊社エンジニアが書き慣れており、もし自分以外の弊社メンバーがこのシステム構築に参加してくれるとなったら、もっとも障壁が低いと思われたからです。 

上記のような検討を経て、今回のSlackアプリは
AWS Elastic Beanstalk + RubyOnRails
の組み合わせで実装することにしました。

AWS Elastic Beanstalkを使った感想

AWS Elastic Beanstalk
はご存知の方も多いと思いますが、アプリケーション構築に必要な各種AWSリソースをElastic Beanstalkのインターフェースからだけで作成、管理できてしまうというものです。たとえば、Webサーバーは通常EC2を使うと思いますが、Elastic Beanstalkを使って開発する場合は、EC2を直接操作するのではなく、Elastic Beanstalkが自動的に作成してくれるEC2インスタンスを利用する形になります。EC2以外にもロードバランサやデータベース(RDS)、モニタリングもElastic Beanstalkが自動的に作成、管理してくれます。環境を片付ける際も環境を削除すると、それにぶら下がるAWSのリソースがバックグラウンドで削除されます。
Webアプリケーションを作成するためにはたくさんのAWSリソースが必要ですが、Elastic Beanstalkを利用すると、それらを個別に管理する必要がなく、アプリケーションのコード作成に注力できるので、とてもスピーディにアプリケーションをデプロイすることができます。

今回もSlackアプリをスピーディにデプロイするにあたってはElastic Beanstalkがとても大きな役割を果たしたと考えています。

ただ、便利な半面デメリットとしてはリソースに対する細かい制御がしにくい、もしくはできないことがあります。なので、リソースに対する細かな制御が必要になってくるアプリケーションの管理にはElastic Beanstalkは向いていないと思います。

出来上がったSlackアプリについて

出来上がったSlackアプリですが、仕様を簡単に言うと、メンバーが他のメンバーをほめたときに、ポイントを付与するようにする、というものです。
どうやって「ほめる」か?ですが、過去に利用していたSlackアプリのEngazifyはメンション(ほめたい相手)をつけたメッセージに「特定の絵文字」を付けたときに、アプリのボットがそれに反応して、ほめられた相手にポイントを付与する(ほめたメンバーも記録される)というものでした。なので、普段のメッセージングにただ絵文字をつけるだけ、という超わかりやすくシンプルな仕様でした。
ただ、このアプローチは、ボットユーザーが招待されたチャンネルのメッセージをすべて読み取る必要があり、Webサーバー側に高い負荷がかかることが予想されます。実際Engazifyのレスポンスが劣化していったのも、主にこのことに起因すると想像されます。

そこで今回作成するアプリは、

  1. ほめるコマンドを作る
  2. アプリのボットユーザーがメンションされた時をほめたときとみなす

の2つのアプローチを取ることにしました。

1も2もSlackから受け取るイベントはまさに「ほめた」ときのみで、その他のメッセージは受け取らないので、負荷的な問題はクリアできます。

欠点としては、Engazifyに比べるとわかりにくいことが挙げられます。
1の場合は、コマンドを覚えている、もしくはコマンドのリストから探す必要がある
2の場合は、通常の会話にアプリのボットユーザーのメンションを加えるという行為が絵文字に比べると非直感的
といったことが挙げられますが、大した欠点とも思われないので、上記2つを採用することにしました。

で、さしあたりはコマンドを実装して、実際にコマンドを実行してみたところ、こんな感じになりました。

どうですか?

社内で一部のメンバーに見てもらったところ、いろんな意見が出たので、これから、これを改善していこうと考えております。

既存サービスを利用するのではなく、自作のアプリなので、社内の声を聞きながらシステムに反映していくことができます。

これぞ、アプリケーション構築の醍醐味!

なお、このRubyプログラムについては今後github上で公開していく予定です。
また、このアプリを育てていってプロダクト化もしたいな、とか夢は膨らむばかりです。

ところで弊社サービスCarelyでは実はすでにSlackアプリとの連携が実装されています。
CarelyのユーザーはCarely画面内のボタンからSlack連携を許可しておくと、Carelyからのお知らせをメールで受け取ると同時にSlack上で受け取ることができるというものです。
またCarelyは、ランサーズチームスピリットSmartHRといった名だたるWebサービスともすでに連携しており、今後もたくさんのWebサービスとの連携を予定しています。
他のWebサービスとの連携を図りながら、カンパニーヘルスケアのプラットフォームを一緒に作っていく楽しさを分かち合える仲間も募集しています!