Tosainu Lab

SlackのBotを書いてみた

今までメッセージのやり取りをL○NEで行っていた某所が, ついにSlackに移行しました. 非常にめでたい.

んで, 個人的に SlackといったらBot みたいなのがあるので, とりあえずサクッとBot書いてみた時のメモです.
ぶっちゃけ, この手の記事は全世界各言語でいくつもあると思いますが.

Real Time Messaging API

SlackのBotを書き始める前に, まずSlackのAPIがどんな感じになっているかを調べておきます.

SlackにはいくつかのAPIが用意されていますが, その一つである**Real Time Messaging API**(以後RTM)は, その名の通りリアルタイムにSlackの各イベントを受け取ることのできるAPIです.

APIは他にもありますが, 何かイベントが合った時にHTTP POSTリクエストが行われるという各WebhookSlash Commandは, 外からアクセスできるWeb鯖を立てにくい環境にある身としては敷居が高かったので, 今回はRTMを利用することにしました.

Event

RTMを使うことでSlack上で起きた出来事をリアルタイムで取得できるわけですが, それらはEventで区別されています.
受け取ることのできるEventはここに全て載っていますが, 今回は接続を確認するためにhello, 投稿されたメッセージの情報を受け取るためにmessageを使いました.

hello event

サーバとの接続ができた時に送られてくるイベントです.

message event

新しいメッセージが投稿されたり, 編集/削除されたときに送られてきます.
受け取ることができる主な情報は

プロパティ名受け取れるデータ
channelメッセーが投稿されたチャンネル固有のID (名前ではない)
userメッセージを投稿したユーザ固有のID (@hogefugaではない)
textメッセージの本文
tsメッセージが投稿された時間

メッセージが編集/削除された時やStarされたメッセージなどはもう少し取れる情報が増えたり形式が変わったりするようですが, その辺に関しては割愛します.

SlackにBot userを追加する

今回作成するBot用のユーザを追加します.

Build Your Own | Slackを開き, 右側のMake a Custom Integrationボタンをクリックします.
custom integratioon

追加したいチームのBuild a Custom Integrationページに移動したら, Botsを選択.
make bot

任意のUsernameを設定して完了です.
username

Integration SettingsのAPI Tokenを後で使うので控えておきます.
token

slack-ruby-clientでBotを書く

Twitter APIのときみたいに C++でOAuthから手書き~ みたいなことも考えましたが, 今回使いたかったRTMはWebSocketベースのAPIらしく, 暇もないしちょーっと大変そうだなーと思ったので, 今回はRubyで書きました.
Slackの利用者にプログラマが多いせいか, Node.jsRubyといったWebアプリ界隈に人気の言語を中心に各言語でライブラリが揃っており, 比較的扱いやすいプラットフォームなのではないかなーという印象を受けました.

  • Ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]
  • Bundler 1.11.2
  • slack-ruby-client 0.5.4

RTM Clientを使う

まぁ公式のREADMEやドキュメントを見ればいいのですが, こんな感じに書くようです.

require 'slack-ruby-client'

Slack.configure do |conf|
  # 先ほど控えておいたAPI Tokenをセット
  conf.token = 'API Token'
end

# RTM Clientのインスタンスを生成
client = Slack::RealTime::Client.new

# hello eventを受け取った時の処理
client.on :hello do
  puts 'connected!'
end

# message eventを受け取った時の処理
client.on :message do |data|
  case data['text']
  when 'にゃーん' then
    # textが 'にゃーん' だったらそのチャンネルに 'Λ__Λ' を投稿
    client.message channel: data['channel'], text:'Λ__Λ'
  end
end

# Slackに接続
client.start!

こんな感じのGemfileを作成して

source 'https://rubygems.org'

gem 'slack-ruby-client'

# RTM Clientを使うとき必要
gem 'eventmachine'
gem 'faye-websocket'

こんな感じに実行すれば…

// 依存するGemのインストール (最初だけ必要)
$ bundle install --path vendor/bundle

// Botの実行 (上のソースをbot.rbで保存している場合)
$ bundle exec ruby bot.rb

コードを実行して結果を返すBot作った

某所Slackに C++で困ったら誰かが教えてくれる場所 というチャンネルを立てたので, 他所のSlackで見たことのある見出し通りのBotがあると便利そうだなーと思っていたので作りました.
https://gist.github.com/Tosainu/6b9eb76e56bdceaacb15

slack

Bot宛のDM, もしくはBotを招待したチャンネルで

run C++ code

もしくは

run:language code

といったメッセージを投稿すると, オンラインコンパイラWandboxのAPIを叩き, 結果を投稿してくれます!!

おわり

Slack便利すぎる…