その他
    ホーム 技術発信 DoRuby Slack Web API であそぼ
    Slack Web API であそぼ
     

    Slack Web API であそぼ

    この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

    Slack Web APIで遊びます。 もともと難しくないと思いますが、rubyだと gemを使えばさらにかんたんです。

    とりあえず今回使ってみるgem, slack-apiのリポジトリとドキュメントです。

    slack-apiを使ってみよう

    トークンの取得

    Slack APIを使うために、まずトークンをとってきましょう。

    https://api.slack.com/

    の “Start Building” から適当な名前 (私は「あああああ」にしました) とAPIを使いたいチームを選ぶとAppができます。
    OAuth & Permissionsから 適当な Permission Scopeを1つ以上 (私は emoji:read にしました) 選んで保存、ページ上の方の Install App to Team からアプリをインストール?するとトークンが発行されます。OAuth Access Token というのがそれです。

    トークンがあると、API経由でトークンを発行したアカウントとして色々なことができてしまうので、これは基本的に人に見せてはいけないものです。
    ソースコードをgitで管理するときは注意しましょう。私はよくうっかりコミットしています。

    やってみよう(その1)

    トークンを取得したらslack-apiを試してみましょう。
    ドキュメントの http://www.rubydoc.info/gems/slack-api のコードの "YOUR_TOKEN" をさっきのトークンに置き換えて実行してみましょう。

    require "slack"
    
    Slack.configure do |config|
      config.token = "YOUR_TOKEN"
    end
    
    Slack.auth_test
    

    コンソールでこれをそのまま実行すると、認証に成功しようが失敗しようが特に何も表示されません。

    p なり何なりで Slack.auth_test の返り値を見てみると、認証に成功した場合はURLなどが、失敗した場合はエラーの内容がhashで返ってきます。
    基本的にはSlack Web API https://api.slack.com/web のそのままです。slack-apiはトークンまわりやJSONのparseをしてくれるだけで、このあたりは自力です。DIYです。

    # 成功した場合
    {"ok"=>true, "url"=>"https://hoge.slack.com/", "team"=>"hoge", "user"=>"fuga", "team_id"=>"TXXXXXXXX", "user_id"=>"UXXXXXXXX"}
    # 失敗した場合
    {"ok"=>false, "error"=>"invalid_auth"}
    

    やってみよう(その2)

    もうちょっと意味のあるAPIを叩いてみたいですね。何かないでしょうか。

    https://api.slack.com/methodshttp://www.rubydoc.info/gems/slack-api/Slack/Endpoint

    あたりを見比べてやっていきます。
    slack-apiのドキュメントにはどういったパラメータを指定すればよいかは書いていないので、そちらはslack apiのメソッド一覧を見てがんばります。

    とりあえず役に立ちそうなものとして、ユーザーの一覧 を取得してみます。
    https://api.slack.com/methods/users.list を見るに、必須パラメータはトークンだけですが、そのトークンはslack-apiがなんとかしてくれます。

    permission がない場合はエラーになります。必要なものが何か返ってくるので、最初にしたように permission を追加してあげましょう。
    emoji:read しかpermissionを与えていないと当然ですが駄目です。言われるがままに users:readを追加しましょう。

    > Slack.users_list
    => {"ok"=>false, "error"=>"missing_scope", "needed"=>"users:read", "provided"=>"identify,emoji:read"}
    

    permission を 追加すると何かメッセージが上に出てくると思いますが、reinstallする必要があります。
    permission を追加すれば無事にできます。せっかくなので実行例を貼りますが、情報の大洪水です。ぜひ読み飛ばしてください。

    > Slack.users_list
    => {"ok"=>true,
     "members"=>
      [{"id"=>"UXXXXXXXX",
        "team_id"=>"TXXXXXXXX",
        "name"=>"fugahoge",
        "deleted"=>false,
        "color"=>"4bbe2e",
        "real_name"=>"Hoge Fugefuga",
        "tz"=>"Asia/Tokyo",
        "tz_label"=>"Japan Standard Time",
        "tz_offset"=>32400,
        "profile"=>
         {"first_name"=>"Hoge",
          "last_name"=>"Fugafuge",
          "avatar_hash"=>"db6076802fe8",
          "image_24"=>"https://avatars.slack-edge.com/2000-00-00/173314781776_db6076802fe8e541e650_24.png",
          "image_32"=>"https://avatars.slack-edge.com/2000-00-00/173314781776_db6076802fe8e541e650_32.png",
          "image_48"=>"https://avatars.slack-edge.com/2000-00-00/173314781776_db6076802fe8e541e650_48.png",
          "image_72"=>"https://avatars.slack-edge.com/2000-00-00/173314781776_db6076802fe8e541e650_72.png",
          "image_192"=>"https://avatars.slack-edge.com/2000-00-00/173314781776_db6076802fe8e541e650_192.png",
          "image_512"=>"https://avatars.slack-edge.com/2000-00-00/173314781776_db6076802fe8e541e650_512.png",
          "image_1024"=>"https://avatars.slack-edge.com/2000-00-00/173314781776_db6076802fe8e541e650_1024.png",
          "image_original"=>"https://avatars.slack-edge.com/2000-00-00/173314781776_db6076802fe8e541e650_original.png",
          "status_text"=>"あああああああああ",
          "status_emoji"=>":star:",
          "real_name"=>"Hoge Fugafuga",
          "real_name_normalized"=>"Hoge Fugafuga",
          "team"=>"TXXXXXXXX"},
        "is_admin"=>true,
        "is_owner"=>false,
        "is_primary_owner"=>false,
        "is_restricted"=>false,
        "is_ultra_restricted"=>false,
        "is_bot"=>false,
        "updated"=>1501299574,
        "is_app_user"=>false,
        "has_2fa"=>false},
       {"id"=>"USLACKBOT",
        "team_id"=>"TXXXXXXXX",
        "name"=>"slackbot",
        "deleted"=>false,
        "color"=>"757575",
        "real_name"=>"slackbot",
        "tz"=>nil,
        "tz_label"=>"Pacific Daylight Time",
        "tz_offset"=>-25200,
        "profile"=>
         {"first_name"=>"slackbot",
          "last_name"=>"",
          "image_24"=>"https://a.slack-edge.com/0180/img/slackbot_24.png",
          "image_32"=>"https://a.slack-edge.com/2fac/plugins/slackbot/assets/service_32.png",
          "image_48"=>"https://a.slack-edge.com/2fac/plugins/slackbot/assets/service_48.png",
          "image_72"=>"https://a.slack-edge.com/0180/img/slackbot_72.png",
          "image_192"=>"https://a.slack-edge.com/66f9/img/slackbot_192.png",
          "image_512"=>"https://a.slack-edge.com/1801/img/slackbot_512.png",
          "avatar_hash"=>"sv1444671949",
          "always_active"=>true,
          "real_name"=>"slackbot",
          "real_name_normalized"=>"slackbot",
          "fields"=>nil,
          "team"=>"TXXXXXXXX"},
        "is_admin"=>false,
        "is_owner"=>false,
        "is_primary_owner"=>false,
        "is_restricted"=>false,
        "is_ultra_restricted"=>false,
        "is_bot"=>false,
        "updated"=>0,
        "is_app_user"=>false}],
     "cache_ts"=>1501754086}
    

    いろんな情報が返ってきますね。slackbot の is_bot が false なのが得心いきませんが、こういうもののようです。

    idなる文字列 "UXXXXXXXX" がありますが、発言ログなどを取ったときやAPIで投稿するとき、 Slack API ではこれを使います。
    チャンネルも同様に “CXXXXXXXX” などになります。idは変わらないので決め打ちでもよいのですが、そうもいかない場合は自力で照合してやりましょう。

    permission に users:read.email を追加すると、メールアドレスも返ってくるようになります。

    やってみよう(その3)

    迷惑ユーザーなのでslackの同じチームのユーザー全員にdirect messegeを送りつけたくなりました(ジョークです)。

    direct messageを送りつけるのはかんたんです。
    https://api.slack.com/methods/chat.postMessage を見るに、宛先と本文(とトークン)さえあれば送れます。
    手始めにslackbotに送ってみます。channelはユーザーid(Uから始まる方)、textは適当な文章でやってみます。
    前のusers.listの結果を見るに slackbotのユーザーidは “USLACKBOT” です。

    > Slack.chat_postMessage(channel: "USLACKBOT", text: "あああああ")
    => {"ok"=>true,
     "channel"=>"DXXXXXX",
     "ts"=>"1501756000.743447",
     "message"=>{"type"=>"message", "user"=>"UXXXXXXXX", "text"=>"あああああ", "bot_id"=>"BXXXXXXXX", "ts"=>"1501756000.743447"}}
    

    slackbotには何言ってんの?という反応をいただきました。

    enter image description here

    実は Slack API 的には、UやCから始まる例のidでなくてもメッセージが送れます。

    > Slack.chat_postMessage(channel: "@slackbot", text: "あああああ")
    => {"ok"=>true,
     "channel"=>"DXXXXXX",
     "ts"=>"1501756000.743447",
     "message"=>{"type"=>"message", "user"=>"UXXXXXXXX", "text"=>"あああああ", "bot_id"=>"BXXXXXXXX", "ts"=>"1501756000.743447"}}
    

    さて、ここまでやったことを活かせば、無事に1行で迷惑ユーザーになれます。

    Slack.users_list["members"].each {|member| Slack.chat_postMessage(channel: member["id"], text: "あああああ")}
    

    間違いなく顰蹙を買うので実行するのはやめたほうがいいと思います。

    まとめ

    これでslackでなんでもできる気がする!!!!!!!

    実際permissonさえ追加すればユーザーとしてできることはたいていできるはずです。

    おまけ

    派生?gemが存在して、slack-apiよりもこちらの方が若干APIのレスポンスを丁寧に返してくれます。
    https://github.com/slack-ruby/slack-ruby-client

    また、Real Time Messaging APIもgemから使えます。
    Real Time Messaging API は botトークンでないと使えないので注意です。({"ok":false,"error":"not_authed"} ……)

    Real Time Messaging API は 先駆者がいるので (名言botをslackに入れて「人生」とは何か考えよう )ここではあまり言及しません。

    gemを使う場合もそこまで変わらず、違うのは

    • rtm.start からurlを受け取ったり Faye::WebSocket::Client.new(url) したりするくだりが全部まとめて Slack.realtime でいい
    • JSONもparseしたりしなくていい

    くらいです。

    Slack API を組み合わせて君だけの最高のbotを作ろう!