Slackで業務チャンネルの平穏を維持するbot、そして人間のトークンをbotに与える話

<div class="alert alert-success text-center"><i class="fa fa-slack"></i> この記事は <a href="http://qiita.com/advent-calendar/2016/slack">『Slack Advent Calendar 2016』</a>1日目の記事です。</div>

![slack2.jpg](https://qiita-image-store.s3.amazonaws.com/0/25109/db29e9b0-9006-159a-a7df-d9d8174ebc7d.jpeg)
2016年もSlackが熱い一年でした！
ビデオチャット機能の追加や、Electronで一新された新クライアントの公開など、Slackの勢いはまだまだ止まりそうにもありません。
皆様も日頃からコミュニケーションにSlackを活用されていることかと思います。

…しかし、コミュニケーションというものはやはり難しいものです。
数多くのメンバーが所属していると、ときに問題が起きることがあります。

本日はSlackAdvent Calendar 2016 1日目を記念致しまして、
そういった問題の例示とその対処法を紹介します。


## 特定チャンネルの秩序と均衡を維持する

\#general のような特別なチャンネルを除き、
誰も出られないチャンネルというものを作成することはできません。

そのため、重要なチャンネルから勝手にleaveしたり等、
**【反逆行為】**に手を染める**【レジスタンス】**が発生することがあります。

この度、こういった**【愚かな反逆者】**を封殺し、
チャンネルに**【秩序と均衡】**をもたらすbotを開発いたしましたので
賢明なる皆様にご紹介致します。

## Alijigock - 秩序と均衡を維持する門番

![アリジゴク（いらすとや）](https://qiita-image-store.s3.amazonaws.com/0/25109/9e4e6774-6059-f467-4fac-68d5827ddc62.png)

[rutan/alijigock: Alijigock is a employee management bot for Slack](https://github.com/rutan/alijigock)

Alijigock（ありじごっく）は自身が所属する公開チャンネルの
**【秩序と均衡】**を維持し続けるbotです。

### チャンネルからのleave禁止

まずは、こちらの画像をご覧ください。

![leave.png](https://qiita-image-store.s3.amazonaws.com/0/25109/94b097de-9943-762e-ab1c-17b17762fdbf.png)

これは僕の頭がおかしくなったわけではなく、
leaveした瞬間にalijigockによって再inviteされている様子です。
leaveから約0.5秒ほどでinviteが完了します。

また、再invite時には**【反逆者】**の名前を **`@channel`** で通知することで、
メンバーによる**【正義の制裁】**を推奨しています。

### チャンネルのarchive禁止

チャンネルが出られなくなったことにより
自暴自棄となった**【反逆者】**がチャンネルのarchive化コマンドを
実行する可能性が想定されます。

![archive.png](https://qiita-image-store.s3.amazonaws.com/0/25109/0551f486-f8e8-4608-83db-2f413f5343b1.png)

Alijigockは各種Slackイベントの監視を行っているため、
archiveコマンドを検知後、即座にunarchiveコマンドを実行します。

また、Slackのunarchiveコマンドは、
元々チャンネルにいたメンバーを取りこぼすことがあるのですが、
Alijigockは誰がチャンネルに所属していたかを記憶しているため、
1人も逃走を許すことなくチャンネルへの再inviteを実行します。[^1]

[^1]: 今日発覚したのですが、実は現時点での実装だと自分がjoinしていない部屋のarchive化も防ぎます。やばい。

以上がAlijigockの機能の概要です。
賢明なる皆様であれば、この素晴らしさがご理解頂けると思います。

## SlackのBot integrationについて

[Bot Users \| Slack](https://api.slack.com/bot-users)

SlackのBot Userは人間のアカウントとは別のトークンで
様々なAPIを叩くことができるため便利なのですが、
一部のAPI利用については制限があります。

その代表となるのが、チャンネル作成系に関するAPIです。
これにはチャンネル作成はもちろんのこと、inviteなども含まれています。

そのため、
**「カレンダーに予定を追加したら、
　予定のメンバーが入ってるチャンネルを自動的に作ってよ！」**
みたいなよくある要求も、botトークンだけだと実現が難しかったりします。

### 人間の権限でAPIを実行する

botにできないなら人間がやればいいじゃない。

とはいうものの、[SlackのAPIテストページ](https://api.slack.com/docs/oauth-test-tokens)で取得できるトークンは、
チャンネル作成どころか何でもできちゃう激ヤバ権限トークンなので、
あまりアプリケーションに組み込んだりはしたくありません。

どうしたもんかな〜と思っていたのですが、
SlackBreakerの知人に『OAuthでスコープを絞ったトークンを発行するといいよ』
と教えてもらったので皆様にもご紹介します。

## OAuthでトークンを取得する

Slack APIの認可にはOAuth2が使用されています。
いつもAPI叩くときに付けてるあのトークンですね。

1. Slackアプリ登録をする
2. OAuthでコード取得 → アクセストークン取得を実行する

の手順で取得することができます。

### アプリを登録する

Slackアプリケーションの登録をすることで、scopeを指定したトークンを取得することができます。
まずは、SlackアプリケーションのClientIDの発行が必要なため、
以下のページでアプリケーションの作成を行ってください。
[Slack API: Applications \| Slack](https://api.slack.com/apps?new_app=1)

<img src="https://qiita-image-store.s3.amazonaws.com/0/25109/9c170efa-b054-5813-19c9-21f99808b5ac.png" width="320">

アプリ名とかは何でもいいです。
作成すると Client ID と Client Secret が表示されるのでチェックです。

### トークンを取得する

アプリのClient IDが手に入ったら各種パラメータを付けて、
Slackのエンドポイントを叩くことでトークンが手に入ります。

- 参考： [SlackでOAuth2を利用したときのメモ \- Qiita](http://qiita.com/subarunari/items/3e4c6060fcefd4c65257)

OAuth2はシンプルなので、自分でURLを組み立ててブラウザで踏めば良いのですが、
URLを組み立てるのすら面倒なので、専用のページをつくってみました。

<img src="https://qiita-image-store.s3.amazonaws.com/0/25109/ceaeb0b6-c223-a98a-4203-ba89fc9dc418.png" width="320">

- <a href="https://rutan.github.io/get-slack-token/">Get Slack Token</a>

Client ID / Client Secret / 認可したいscopeを用意して、
上記のページに入力してポチポチするとAccessTokenが返ってきます。

認可するscopeについて、どういった区分になっているのかは
下記のページをご確認ください（よく増えるので）。

- [OAuth Scopes \| Slack](https://api.slack.com/docs/oauth-scopes)

## まとめ

本記事では、Botユーザーが叩けないAPIを利用したい場合は
OAuthで取得した人間のトークンを併用する、という方法をご紹介しました。

人間のトークンでしか実行できないAPIが利用できるようになると、
チャンネル作成、検索、ファイルアップロードなどなど
Slack botでできる幅が広がります。

用法、容量を守って楽しくハッピーSlacking！

----------

本記事で紹介しておりますAlijigockのアイコン画像には
以下のものを使用しています。
[アリジゴクのイラスト \| かわいいフリー素材集 いらすとや](http://www.irasutoya.com/2016/11/blog-post_450.html)


また、[Slack その2 Advent Calendar 2016](http://qiita.com/advent-calendar/2016/slack2) がまだまだ空きがあるみたいです！
さっき見たら1日目も埋まってなかったので、そっちも参加してみました。
何か小ネタお持ちの方は是非参加しましょう！

<a href="http://niconare.nicovideo.jp/watch/kn2026"><img src="https://qiita-image-store.s3.amazonaws.com/0/25109/f9d76e98-959d-20a7-11d1-5744efe36799.png"></a>

- [SlackのMarkdownっぽい謎のフォーマットを倒した話【Slack その2 Advent Calendar 2016】](http://niconare.nicovideo.jp/watch/kn2026)