この記事は 『Slack Advent Calendar 2016』2日目の記事です。
昨日はru_shalmさんの「Slackで業務チャンネルの平穏を維持するbot、そして人間のトークンをbotに与える話」でした。
Slackで何が起こっているか、知ってますか?
Slackはいつでもそこにいるわけですが、実際に自分が観測しているSlackの世界は意外と限定的です。自分がjoinしているチャネルで何の発言がされて、自分がどんなリアクションを付けられ、またあるいはアットマークを付けて呼び出される、くらいの情報しか通常は知る方法がありません。
しかし、Slackにはあなたの知らないたくさんのチャネルがあり、そのたくさんのチャネルでは沢山の人達が会話を楽しみリアクションを付けたり、また新しいチャネルを作ったりチャネルをアーカイブしたりしています。もしかしたら、新しい絵文字を追加しているかもしれないし、登録した絵文字を消しているかもしれません。自分が所属している組織では、2016年12月2日2時14分現在、2478個のチャネルがあり、4496個の絵文字が登録されています。それに対して、自分が参加しているチャネルは100程度と、知っているSlackの世界はごく限られた一部だけです。
数人しか参加していない、規模の小さな Slack team であれば、もしかしたらあなたはSlackの世界で起こっているすべてのことを知っているかもしれません。すべてのチャネルに参加し、すべての発言やリアクションを見ることができます。ですが、誰かが発言し、すぐに削除した発言は見ることが出来るでしょうか? 誰かがこっそり作った(プライベートではない)チャネルの存在を、知ることは出来るでしょうか?
Slackには、クライアントを作成するために用意されている、Slackの世界を知るための方法が用意されています。というよりも、種々の便利なbotを作ろうと思うと、このAPIを避けて通れません。それが、Real Time Messaging APIです。
Real Time Messaging APIから飛んでくる通知を、逐一どこかのチャネルに(どこのチームにもbotの練習をするためのチャネルが必ずいくつかあると思いますが、その中で最も活発なチャネルがオススメです)逐一流すことで、今そこにあるSlackで何が起こっているのかを知ることが出来ます。
わりと簡単に作れると思いますが、一応私が作ったテキトーな実装をご紹介しておきます。
一年以上前からゆるく運用し続けているコードで、使ってるGemが古かったり微妙な実装が多いので、リポジトリにしないでGistにしました。時間があったらちゃんとGemにしますが、今回はちょっとこのコードでお茶を濁させてください。大した規模のコードでもないので、このコードは参考程度にして、ご自分で実装することをオススメします。
ある日のリアルタイム通知botの様子
Caution
このbotをSlackに放つ前に、よく考える必要があります。というのも、このbotは基本的に嫌われます。そしてそのbotをSlackに放ったあなたも嫌われることでしょう。
このbotは、Slackで起こっているありとあらゆることを可視化します。その結果、様々な人から「本当は知られたくなかった」ことを暴かれたとして、厄介者を蔑む目で見られることでしょう。
例えば、仲間内でこっそりと楽しむために作ったチャネルに、どこからやってきたのかわからない人が突然たくさんjoinしてきます。当然このbotの通知を見て興味を持った人が参加したのですが、チャネルを作った本人は、Real Time Messaging API の存在など知らず、一体どうやって新しく作ったばかりのチャネルを補足されたのか、気味悪がることでしょう。個人的にはprivateチャネルでやればいいと思うのですが、どうもIRCのように、クローズではないけど名前を知らないと入れないチャネルを求めている人は想像以上に多いのです。
「どうしてSlackで起こったことをいちいち監視して、あまつさえそれをチャネルに流すのか」と罵られることもあります。とはいえ、このbotで知り得ることは当然公開情報であり、privateチャネルなどで起こっていることは捕捉できません。公開されている情報を可視化したからといって何故責められるいわれがあるのでしょう。とはいえ、そのような正論ぶったことを面と向かって相手に言うと、当然ながらさらなる怒りをかうだけなので、私はよく「公開されている情報をここであえて公開することによって、こっそりと監視するというストーカーみたいなモチベーションを削ぐ効果がある」と、言い訳になっていない言い訳をします。
心の底から本音を言うと、このbotの本当の目的は、圧倒的な権力を持ったアドミニストレーターという特権階級に対して、その力を不用意に乱用することが無いかどうかを監視する、いわば民主主義のような観点のつもりで作ったのですが、実際のところ私が所属している組織のSlackを管理しているアドミニストレーターたちは特に権力を乱用している様子もなく、運用も平和そのものなので、ただ単に私が憎まれるだけの結果になっています。
Real Time Messaging API
Slackで今起こっているたくさんのイベントを、勝手に教え続けてくれるWebSocketのAPIです。Slackのクライアントを作成するには、新しく作られたチャネルや、新しく追加された絵文字、新しくチームに参加したユーザーを常に知っている必要があります。さすがに、すべてのチャネルにポストされた投稿を逐一教えてくれることはありませんが、大抵の情報を教えてくれます。
非常にたくさんのイベントを通知してくれますが、私が特に重宝しているイベントを、アルファベット順に共有します。
bot_added event
https://api.slack.com/events/bot_added
新たにbotが追加された時に通知が来ます。新しいIntegrationが追加された時や、新しいOAuthトークンが発行されたことなども教えてくれます。
誰かが何やらよくわからないOAuthなどを発行した時に真っ先に教えてくれるので、組織内で謎の闇サービスが誕生したことを最初に知ることができます。
channel_archive event / channel_created event / channel_rename event / channel_unarchive event
https://api.slack.com/events/channel_archive
https://api.slack.com/events/channel_created
https://api.slack.com/events/channel_unarchive
https://api.slack.com/events/channel_rename
チャネルに何か変化があった時に通知されます。RTMは、基本的に自分がjoinしていないチャネルに関しても、すべてを教えてくれます。
1日目のru_shalmさんが作っていた蟻地獄botも、このイベントを参照しているはずです。
emoji_changed event
https://api.slack.com/events/emoji_changed
絵文字に何か変化があったときに通知されます。先述のchannel系のイベントと違い、サブタイプがやたらと多く定義されていて、サブタイプによって挙動を変えなくてはいけません。SlackのAPIによくある構造の統一性がちぐはぐなやつで、心がほっこりする気持ちになれます。
reaction_added event / reaction_removed event
https://api.slack.com/events/reaction_added
https://api.slack.com/events/reaction_removed
リアクションが付いたり消えたりした時に来るイベントです。これもチャネルの参加を問わずすべて通知してくれるので、便利です。リアクションが付くということは、何かしら情報量の多いPOSTである可能性が高いので、これを通知するとウケますし、同時に顰蹙をかいます。
ちなみに、starに関するRTMもあるのですが、なんかしらないけどいつの間にか「あ、それあんまり使ってる人居ないから廃止したわ」とか、同僚のSlackBreakers(注:どういうわけか、私の所属している組織では、Slackが好きでたまらない人たちのことを、SlackBreakersと呼ぶ風習があります)はSlack社に言われてたので、現在は使えるかどうかよくわかりません。
team_join event
https://api.slack.com/events/team_join
新たにチームに参加したメンバーが居るときに通知されます。こういのを監視してると、ストーカーと言われます。
ちなみに
RTMは本来Slackクライアントを想定して作られていると思われるので、あまりにたくさんの情報をブロードキャストする上に、その組織に所属する人しか参照することが出来ず、Slack Appを作るには不向きでした。そこで、Events API という、OAuthのスコープで参照を許可させることが出来るAPIも存在します。しかし、自らの所属する組織のイベントを参照するにはやや手順が大げさで面倒なので、Slack Appを真面目に作る以外の用途で利用することは今のところなさそうです。
実装の勘所
勘所というほど大層なものでもないですが、運用していていくつか困る点があったので共有します
Slackは勝手にチャネル名を書き換える
チャネル名が変わった時、フツーに #hogehoge のようにPostすると、変更後にSlackが余計な気を利かせて、過去にさかのぼってすべてのチャネルの表示名を書き換えます。これはチャネルに限ったことではなく、Slackの特殊なMarkdownを使っている場合はたいてい起こるケースです。そのため、チャネル名の変更などを検知するときは、キャッシュに残っていたデータと新たに取得したデータを付きあわせて、Markdownを使わずに記述することで、Slackの余計なお世話を回避することが出来ます。
SlackのWebSocketは突然キレる
どんなサービスでもそうだと思いますが、WebSocketは突然一方的に遮断されるものです。リトライ機構を設けましょう。
APIの結果はできるだけ頑張ってキャッシュする
SlackのAPIは、大きな組織で使っていると正直レスポンスがでかすぎて、色々辛くなる上に重いです。しかし、このbotは基本的に今までSlack上に無かったものが増えたことを教えてくれるので、キャッシュに頼ると死にます。なので、キャッシュコントロールはがんばりましょう。
無限ループに気をつける
これもbotあるあるだと思いますが、自分の発したメッセージに反応して、核分裂でも起こしたかのような急激な無限ループが発生することがあります。今回のGistには入れていませんが、特定のキーワードに反応するときは気をつけましょう。
余談
RTMを使えば、特定の誰かがオンラインになったとかオフラインになったとかもわかります。つまり、誰もが気になるあの人がSlackでオンラインになったりすると、それを教えてくれるbotとかも作れたりします。需要があるかどうかは知りませんが、組織の誰もが知りたい人物のオンライン情報とかがあれば使ってください。
まとめ
まあだいたい、これくらいのイベントを見ていれば、立派にストーカー扱いされますな情報通です。
先に強調したとおり、RTMが教えてくれることは、botのトークンを使う限りはprivate groupなどの秘匿情報を一切含んでおらず、あくまでSlackのチーム全員に公開されている情報なので、非常に有益です。
みなさんもぜひ、今そこにあるSlackをリアルタイムで可視化し、世界を知りましょう。