bot scopeを付与したAnketをリリースした話とbot scopeがなぜ必要なのかの話

blog.hatappi.me

Anket を初回リリースしてから195日くらいたちました。
今回のリリースではちょっと大きめ?のリリースをしたのでブログを書こうと思います。

今回のリリースでは Anket に bot scope を追加しました 🎉

この記事ではリリースした機能の紹介と機能を提供するためになぜ bot scope を追加する必要があったのかを書きます。

リリースした機能の紹介

bot scope を追加し、それを使って WEB 上からアンケートを作成できるようになりました。
※ 今回リリースした機能はまだ実験段階なので今後変更される可能性があります

利用手順

  • Anket Botワークスペースに追加する必要があるため既にAnketがインストールされている場合は再インストールします。
    f:id:hatappi1225:20190605102416p:plain
  • アンケートを投稿したいチャンネルに bot を invite する
    • #general に投稿したい場合は #general で /invite @anket をします。
  • https://app.anket.life/questions/new にアクセスして必要なフィールドを埋めてアンケートを作成します。

f:id:hatappi1225:20190604235206p:plain

これで指定したチャンネルにアンケートが作成されると思います。
もし動かないなどありましたら教えてください!

なぜ bot scope を追加したのか?

ここからはこの機能を提供するためになぜ bot scope を追加したのかを書いていきます。
正直なところ bot scope は追加したくありませんでした。
なぜなのかは以前のツイートにあります。

今までの Anket は slash command を実行するための権限しか付与していませんでした。
しかし slash command はユーザーSlack上で /anket hoge のようにアクションを起こさないとAnket は何もできません。
Anket が活躍できる場が広がることを考えた時に Anket の ダッシュボード上からアンケートつくれたり API 提供してユーザーが API にリクエストして Slack にアンケートを作成できたら面白いのではと思いました。
しかし slash command だけではどうしようもありません。
ではどうするか?

最初に思いつくのが incoming webhooks でした。
これはメッセージの送信しかできないので権限としては必要最低限で良さそうです。
しかし問題があります。

それはドキュメントに記載されているこちらの文です。

You cannot override the default channel (chosen by the user who installed your app), username, or icon when you're using Incoming Webhooks to post messages. Instead, these values will always inherit from the associated Slack app configuration.

インストール時に設定したチャネルを上書きして別のチャネルを指定するみたいなことができないのです。
つまり投稿したいチャンネルができたら incoming-webhooks でチャネルを指定する必要があります。
これは面倒ですね。。。。

bot scope を使えばユーザーは投稿したいチャネルに bot をinvite するだけでアンケートを作成することができるようになります。
incoming webhooks よりも手軽そうです。

なぜ bot scope を追加するのは悩ましいのか

ここまで見た方は普通に bot 権限を付与するので良いのではと思ったかもしれません。
たしかにやりたいことは実現できます。
しかし今回のやりたいことである任意のチャネルにメッセージを送信するという目的に対して bot scope は権限を持ちすぎています。

特に気になっているのは bot 権限を付与するとメッセージのやりとりを受け取ることができることです。
Slack には Real Time Messageing API というものが提供されていて、ユーザーがスタンプうった!チャネルにジョインした!といったアクションを受け取りアクションすることができます。
その中にメッセージがポストされたというイベントがあります。

このイベントを拾うことで投稿されたメッセージを見ることができます。

以下は検証コードです。
今回は botkit v0.7.4 で検証しています。

controller.on('create_bot',function(bot, user) {
  bot.startRTM(function(err){
    if (err) {
        throw new Error(err);
    }
  })
});

controller.hears(['hello','hi'],['direct_message','direct_mention','mention'],function(bot,message) {
    bot.reply(message,"Hello.");
});

これは bot に対して mentionつけたりして hi とか送ると Hello. と返ってくるシンプルな botです。

ここに次のコードを追加します。

controller.middleware.ingest.use(function(bot, message: , _res: any, next: any) {
  console.log(message.text);
  next();
});

これは botkit で提供されている middleware で受け取ったメッセージを閲覧できるようになります。
実行してみると Slack にメッセージが投稿されると log にそのメッセージが出力されます。

Anket ではどうしたのか

現状は Anket でメッセージを受け取ってアクションする必要はないので RTM は使用していません。
それの証明として Slack 上で Bot が Active (緑色になっている) になっているかどうかで判定できます。

f:id:hatappi1225:20190604230333p:plain

この緑は Bot 権限を追加する時に常時ONにするかOFFにするかを選ぶことができます。
OFF にした場合は RTM API を使わない限り緑色にはなりません。

f:id:hatappi1225:20190605103232p:plain

審査

審査に関しては Update だったからか1度確認のメッセージのやりとりをしたら申請が通ったのであんまり書くことないです。

最後に

今回はリリースした機能と bot scope について追加しました。
RTM API は今の Anket では使いどころがなかったですが、便利な API であることは間違いないので、面白い案ができたら正しく使いたいと思います。

まだ Anket を使ったことない方はこの機会を機にぜひ試してみてください!!

anket.life