slack api で bot を作ってみた

  • 168
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

slack 用 bot の作り方

slack 用の bot を作るには方法がいくつが方法がある.
ruby エンジニアなら litaruboty,node が使えるなら hubot を使うのが簡単だけど,それぞれに一長一短がある.

ruboty はちょっと特殊で,専用の integration があるわけではなくコードをみた限り xmpp を使用するので,誰かのユーザーとしてログインするか(その場合は発言はそのユーザーのものになってしまうはず?),bot 専用のユーザーを作る必要がありそう.もし専用ユーザーを作るとしたら,課金をしている場合は1ユーザーとしてカウントされてしまうので使い難い.

lita/hubot は integration として用意されているので bot とし slack 上にユーザーが常駐する.
この場合は課金対象にはならないけど,1 integration 消費してしまう.

たまたま別件の bot を作ろうとして api 眺めていたら,api を使う事で integration 枠を消費せず,
且つ既存ユーザーとは別ユーザーとして( bot として)反応できる bot を作れる事がわかったので,試してみた.

と言うわけで slack api を使用して bot を作る

必要なのは slack の api token だけ.token は ここ で確認.
bot は token を発行した自分自身のアカウントとして行動するが,発言をする時は username を変更できる(変更すると名前に bot と追加表示される)ので,あたかも bot として発言ができる.

lita のコードを確認したわけではないのでもしかすればできるかもしれないが,この方法だと file の upload や,channel の archive 等もできるので lita より高機能なのが作れる.
あと integration 枠消費しないのが良い.

TL;DR

https://github.com/takesato/slack-aria
THE AVVENIRE 良過ぎた勢いで生れた.

解説とか

api を使用して bot を作るには slack の realtime api を使う必要がある.
thread 処理書くの面倒だったので今回は aki017/slack-ruby-gem を使用

require 'slack'
Slack.configure {|config| config.token = TOKEN }
client = Slack.realtime

client.on :hello do
  puts 'Successfully connected.'
end

client.on :message do |data|
  # respond to messages
end

client.start

とりあえずこれだけで bot ができあがる.
あとはイベントに対してそれぞれ振る舞いを書けばいい.

RTM API(Real Time Messaging API) のイベントがどんなの使えるかは公式をみるのが早いので Real Time Messaging API | Slack を参照.

メッセージに応答する bot を作る

ユーザーの発言に反応する bot は message イベントを拾えばいい

client.on :message do |data|
  # respond to messages
end

この時, data には発言の情報が色々含まれているので,その内容をチェックして処理を書く.

良く使うのは

  • channel
  • user
  • subtype
  • text

あたり.
subtype で bot の発言 ( data['subtype'] == 'bot_message' ) とか file の upload (data['subtype'] == 'file_share' ) とかがわかる

返事の仕方

返事は realtime api は使わず,普通に web api の方を使う.
web api 自体はシンプルなので slack-ruby-gem を使わないでも簡単に書けるけど,今回は RTM API を使用するのに導入しているので, slack-ruby-gem の web api wrapper を使う

api の種類は API Methods | Slack 参照

今回は発言する処理を書くので chat.postMessage を使う

  params = {
    token = SLACK_TOKEN,
    channel: channel_id.
    username: bot_name,
    text: 'message',
    icon_url: 'http://url/to/icon/imgage'
  } 
  Slack.postMessage params

内容的には incoming webhook とほぼ一緒(ほぼというか完全?)
逆に incoming webhook でも,web api で使えるオプションが使える.

RTM API と組合せるとこんな感じ

client.on :message do |data|
  if data['text'] == 'おはよう' && data['subtype'] != 'bot_message'
    params = {
      token = SLACK_TOKEN,
      channel: data['channel'].
      text: "<@#{data['user']}> おやすみ",
    } 
    Slack.postMessage params
  end
end