SMARTCAMP Engineer Blog

スマートキャンプ株式会社(SMARTCAMP Co., Ltd.)のエンジニアブログです。業務で取り入れた新しい技術や試行錯誤を知見として共有していきます。

Google APIを利用するSlack botの認可周りの課題をフロントの実装なしで解決しちゃった話

どうもこんにちは。22卒としてスマートキャンプに入社したbraavaです。

普段はBOXIL SaaSというtoB向けのSaaS比較サイトの機能開発・運用をしています。

近頃はM-1グランプリやワールドカップで多少寝不足気味でしたが、今回はそんな自分が社内で利用されている日報ツールを改善したお話です。

本稿の対象読者は下記になります。

  • Google APIを叩くSlack botの開発をAPI開発だけで収めたい人
  • 日々入力する日報を改善したい人
  • ある程度、OAuth認可フローについて理解している人
  • (M-1グランプリとワールドカップが好きな人)

日報ツールって??

弊社では日報を#daily_reportというパブリックチャンネルで共有する文化があります。

この文化はNoteにもまとめられており、社員数が大きく増えた今でも存在します。

その日報に当日の予定を乗せるために、Googleカレンダーから自動で予定を取得する日報半自動生成botという日報ツールが生まれました。

そしてこのツールのメンテナンスを自分が引き継ぐことになったのですが、しばらくして以下の課題が見えてきました。

  • 日報ツールの管理者のカレンダーに利用者全員のカレンダーを登録する必要がある
  • GASの知識があまりなく、メンテナンスできる自信がない
  • 自分の日報フォーマットが埋もれてしまう

この日報ツールは管理者アカウントと連携されていたため、100人以上のGoogleカレンダーを下記のように登録する必要がありました。

また、GASに対する知識があまりなく管理者として引き継いだ後、保守運用をできる自信がなかったため、このbotを興味のあるGolangに書き換えようと考えました。

加えて、実際に日報ツールを利用しているユーザーに軽くインタビューをしたところ同じチャンネルに同時刻にたくさんのフォーマットが送られるため自分の日報フォーマットが埋もれてしまうという課題があることにも気づきました。

しかしながら、よくあるGoogle APIを叩くSlackのbotのように、OAuthによる認可フローのフロントエンド実装が億劫でした。

なぜフロントエンドの実装が必要かというと、Googleの認可処理とSlackアカウントへのログインを行い、両者の紐付けをする必要があるためです。(詳しくは後述します)

ただそれだけのためにフロントエンドの実装をするのは面倒ですよね?(だって楽したいですよね)

そのため、下記のような要件で開発をしました。

  • 上記3つの課題を解決する
  • API開発だけする

先にフロントなしでGoogleの認可を終わらせるSlack botのAPIを解説したうえで、日報ツールを書き換えた結果についてお伝えできればなと思います!!

フロントなしでGoogleの認可を終わらせるSlack botのAPI

課題

前述の「管理者のカレンダーに利用者全員のカレンダーを登録する必要がある」というのは利用者のGoogleカレンダーを管理者のGoogleアカウントの権限で閲覧していたためです。

そのため実際に管理者のカレンダーから利用者のカレンダーを登録する必要がありました。

これを解決するために利用者側でGoogleカレンダーのAPIの認可をしてもらい、利用者ごとに生成されたtokenを使ってGoogle APIを叩きます。

tokenを取得+Slack上のユーザーと紐付けて保存するためには、フロントを用意し下記のような処理を書く必要があります。

  1. Slackのアカウントでログイン
  2. Googleの認可する
  3. tokenを取得し、保存する

しかしながら前述の通りバックエンドの実装だけで済ませたかった(決して楽がしたいわけではない)ため後述の解決策でフロントを作らずバックエンドの実装だけで要件を満たすようなbotを作成しました。

どうやって解決したか??

解決案を簡単に述べるとユーザーに頑張ってもらうです。

認可フローの実装は下記です。

  1. ユーザーにブラウザ上でGoogleの認可をしてもらう
  2. 認可のCallbackで設定されているエンドポイントでcodeを受け取る
  3. 受け取ったcodeを使ってAPIを叩く
  4. 受け取ったtokenをブラウザ上で認識しているユーザーと紐付けた形で保存する

今回はフロントを作らないため4ができません。

そのため生成されたcodeをSlack経由で送ってもらうということをユーザーに頑張ってもらいました。

API側でやることはstateの検証とJSON形式でcodeを返却するだけになり、その表示されたcodeをSlackで送ってもらいます。

図で説明するとこのようになります。

  1. Slack上でGoogleの認可URLを発行する
  2. ブラウザに移動してGoogleカレンダーの利用許可(認可)をする
  3. Callbackで設定したエンドポイントではstateの検証だけ行い、codeをそのままブラウザに出力する
  4. ブラウザに出力されたcodeをSlack経由で送ってもらう
  5. Slack上のユーザーとGoogleで認可されたユーザーの紐付けができ、DBに保存する

上記のフローによってGoogleカレンダーに入っている予定を取得できます!!

またGolangのgoogle-apiを叩くライブラリは、AccessTokenの有効期限が切れていた場合でも、RefreshTokenを利用してAccessTokenを良い感じに再取得してくれるので、そこの実装をする必要がありませんでした。

このようにユーザーに頑張ってもらうことで開発コストを抑え(決して楽がしたいわけではない)つつ、Google APIを叩くSlack botを実装しました。

軽くインフラをご紹介します

本節では前述のフローで実装したSlack botのインフラを見てもらいます。

弊社ではインフラ周りはAWSを利用して構築しているため、本botもAWSを利用しました。

  • AWS
    • Lambda
    • API Gateway
    • DynamoDB
    • CloudWatch
  • ServerlessFramework

SlackやGoogle APIなども含んだインフラの構成図はこのような感じです。

個人的にServerlessFrameworkの楽さをすごく実感しました。

現状デプロイはlocalから行っていますが時間があるときにGitHub Actionsからmainブランチへのpushを検知して自動でデプロイするようにしたいなと思っています。

弊社の日報ツール(別名 日報太郎2.0)

前述のbotは弊社でお茶太郎(日報フォーマット)という名前で利用されていました。

今回の改修にあたり日報太郎2.0といういかにもSaaSっぽい名前に解明しています。(小話)

課題は解決できたか??

実際に管理者でもある自分の負担はかなり減り、bot自体のエラー(Google APIが叩けない等)の調査以外は日報太郎2.0を触る機会は減りました。

また認可フローをしっかりと踏むことで若干グレーの運用をしていた既存の日報ツールから、利用者がしっかりと許可したうえでカレンダーを取得することになったのでbot自体の質も上がったのではないかなと思います。

自分の日報フォーマットが埋もれてしまうという課題についても、アプリとのDMや各々好きなチャンネルで、設定されているコマンドを打つことで日報フォーマットが送られてくるようになったため埋もれる心配もなくなりました。

そしてGASからGolangに書き換えたためbotの拡張意欲も生まれ、実際に新しい機能の開発も現在進めています!!

日報太郎2.0の課題

弊社はtoB向けのSaaS比較サイトやIS向けのSaaSを提供していることもありSlack botなどのツールに慣れている社員が多いためユーザーに頑張ってもらうという選択ができました。

しかしながら、連携の際の手順を全社員が見れるようなドキュメントに起こしても、連携方法に関して質問が来ることはたまにあります。 そのためあまりにも手順に関して質問が来る場合などは他の打開策を探す必要があるでしょう。

反響

自分が所属している開発メンバーに実際に日報太郎2.0に関してインタビューをしました。 (ポジティブなことを言ってくださいなんて言っていない)

以下インタビュー内容です。

日報太郎2.0になったことによって自分のフォーマットが埋もれなくなった。

フォーマットを探す=>日報を編集する、という流れだったのがフォーマットを探す工程がなくなったため日報を書く意欲が劇的に改善された。

勝手にフォーマットを送る仕様から、コマンド経由になったことでフォーマットを欲しいときに取れるようになったため、フレックスするときにも関係なくフォーマットを取得できた。(以前まではフォーマットが送られる時間より前に退勤する場合はフォーマットを利用できなかった。)

自動通知設定ができるようになると以前の仕様も踏襲できてよいのではないか。

今後の展望

今回ユーザーに頑張ってもらうということでSlackのコマンドの引数で認可のコールバックで返ってくるcodeを送ってもらっていました。しかしcodeをコマンド経由で送る際のUXが良くないなと感じており、実際にその周辺で質問も来るため、Slackのモーダルを開いてcodeを入力する形式に変更したいなと思っています。

また、弊社では#daily_reportというパブリックチャンネルに全社員が日報を送っています。そのため業務で関わらない人の日報が見れるというメリットがありますが、逆に見たい人の日報が埋もれてしまうというデメリットもあります。

そのデメリット解消のためSlackのEvent APIを利用したフォロー機能を現在開発中です。投稿したユーザーをフォローしている場合、任意のチャンネルに通知してくれる機能です。

まとめ

前任者から日報botを引き継いだ際に認可フローについての課題をユーザーに頑張ってもらうことでフロントなしの実装で解消し、Googleカレンダーの閲覧権限もユーザーに許可してもらうことでbot自体の質向上をしました。

恐らく既存の日報botがなければそもそも改善しようとすら思わず、作ったとしても社内で普及するのに苦労していたと思います。そのため前任者と利用してくれる社内のユーザーには頭が上がらないです!!