HubotでSlackの招待フォームを実装


[JANOG36](http://www.janog.gr.jp/meeting/janog36/)でスタッフをご一緒していた方から，Slackの隠しAPIの存在を教えて貰いました．
これを使うと，管理者が手動でやっていたユーザの招待を，各自が行えるようになります．
既に招待フォームを提供するWebアプリが幾つかあるのですが，今回はHubot上で実装してみました．

  - [Slack API を使いチームへの招待作業を自動化する - Qiita](http://qiita.com/pine613/items/0c9809629ccbaa354f64)
  - [rauchg/slackin · GitHub](https://github.com/rauchg/slackin)

## 招待APIの概要

[Slack API](https://api.slack.com)には載っておらず，Inviteページのソースから発見されたようです．

  - [How I hacked Slack into a community platform with Typeform](https://levels.io/slack-typeform-auto-invite-sign-ups/)

curlコマンドだと，下記のように呼び出せます(URLのTEAMは無くても大丈夫でした)．
また，TOKENはAdmin権限を持ったユーザが発行する必要があります．

```
$ curl -X POST 'https://TEAM.slack.com/api/users.admin.invite' \
--data 'email=EMAIL&token=TOKEN&set_active=true' \
--compressed
```

## Hubot上で実装

[Typetalk](https://typetalk.in/)用に開発していた[Huboco](https://github.com/hico-horiuchi/huboco)でも，同様の招待機能を実装していました．
この場合はAPIの呼び出しに，[Typetalk Adapter](https://github.com/nulab/hubot-typetalk)が持つTOKENを流用していました．

  - [huboco/invite.coffee at master · hico-horiuchi/huboco · GitHub](https://github.com/hico-horiuchi/huboco/blob/master/scripts/invite.coffee)

![typetalk_form.png](https://qiita-image-store.s3.amazonaws.com/0/58742/3a3a8848-4f44-987f-1136-6f4a6a9502ea.png "typetalk_form.png")

しかし，[Slack Adapter](https://github.com/slackhq/hubot-slack)が持つTOKENはAdmin権限が無いため，別途発行する必要があります．
今回は`HUBOT_SLACK_ADMIN_TOKEN`という環境変数で設定することにしました．
実際のコードは長いので，GitHubへのリンクを示します．

  - [kaonashi/invite.coffee at master · hico-horiuchi/kaonashi · GitHub](https://github.com/hico-horiuchi/kaonashi/blob/master/scripts/invite.coffee)

Hubotの`/slack/form`にアクセスすると，メールアドレスの入力フォームが表示されます．
また，`/api/team.info`を使ってチーム名も表示できるようにしてみました．

![slack_form.png](https://qiita-image-store.s3.amazonaws.com/0/58742/61f4ebfb-0e54-8532-fa0e-14adedd28a0c.png "slack_form.png")

フォームを送信すると`/api/users.admin.invite`が呼び出され，結果が表示されます．
既に招待済みなど，エラーの場合はエラーページが表示されるようになっています．

![slack_invite.png](https://qiita-image-store.s3.amazonaws.com/0/58742/d32e4421-66f0-4928-d077-c49b357fb8b8.png "slack_invite.png")

## inviteコマンド

フォームと同様にして，コマンドでもユーザをチームに招待できるようにしてみました．
(実装した後で`/invite_people`コマンドがあることを知りました…．)

```coffeescript
querystring = require('querystring')
request = require('request')
urler = require('url')

module.exports = (robot) ->
  robot.respond /invite\s+(\S+)$/i, (msg) ->
    email = msg.match[1]
    options = {
      url: "https://slack.com/api/users.admin.invite"
      qs:
        'token': process.env.HUBOT_SLACK_ADMIN_TOKEN
        'email': email
        'set_active': true
    }
    request.post options, (err, res, body) ->
      json = JSON.parse(body)
      unless json.ok
        return msg.reply("```\n#{json.error}\n```")
      msg.reply("#{email} を招待しました")
```

## Kaonashi

上記のコードは[Kaonashi](https://github.com/hico-horiuchi/kaonashi)という名前のBotとして運用中です．

![icon.png](https://raw.githubusercontent.com/hico-horiuchi/kaonashi/master/data/icon.png "icon.png")

## Hubot×ChatOps勉強会

08/22(土)に神戸で[第2回 Hubot×ChatOps勉強会](http://hubot-chatops.connpass.com/event/17902/)を開催します!
HubotやChatOpsに興味のある方，Pluginを開発している方など，ぜひお越し下さい．
発表して頂ける方も募集中ですので，[@hico_horiuchi](https://twitter.com/hico_horiuchi)まで気軽にお声掛け下さい．

![4f4f7c00342367d0b2b51d51510dab0a.png](https://connpass-tokyo.s3.amazonaws.com/thumbs/4f/4f/4f4f7c00342367d0b2b51d51510dab0a.png "4f4f7c00342367d0b2b51d51510dab0a.png")