10
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SlackのRTM APIと対話的に戯れてみた

Last updated at Posted at 2020-03-06

Slack RTM APIとは?

RTMはReal Time Messagingの略です。
その名の通り、Slackのサーバーとクライアントがリアルタイムに(かつ双方向に)やり取りするためのAPIです。web socketという仕組みが使われています。

現在はWeb APIEvents APIを使うように推奨されていますが、まだ一応は使えます1

また、RTM APIにしか出来ないこともいくつかあります。

「Web API + Events API」と「RTM API」のどちらを使えばよいかの判断基準はEvents API FAQにまとめられていますが、個人的には

You're building an on-premise integration or have no ability to receive external HTTP requests

つまり

Slackのアプリ(例:ボット)を動かすサーバーを外部に公開したくない/できない

ような場合、RTM APIは非常に便利です2

簡単にRTM APIを使う方法

Slack公式でPythonからRTM APIを使うためのライブラリが公開されています。

slackapi/python-slackclient

単純にボットを作るだけなら、ライブラリを使うのが手っ取り早いです。

あえてAPIを直にたたく

冒頭でも述べたようにRTM APIはweb socketという仕組みで実現されています。
勉強のために、このweb socketを直接触ってみようと思います!

下準備

まずはwebsocatというコマンドを導入します。
インストール方法の詳細はリポジトリのREADMEを見てほしいのですが、自分の環境(Ubuntu18.04)では次のようにインストールしました

# debファイルをいい感じにインストールしてくれるコマンドを導入しておく
# debファイルがインストールできさえすれば良いので他のコマンドでも可
$ sudo apt install gdebi
# websocatのdebファイルのダウンロード
$ wget https://github.com/vi/websocat/releases/download/v1.5.0/websocat_1.5.0_ssl1.1_amd64.deb
# debファイルのインストール
$ sudo gdebi install websocat_1.5.0_ssl1.1_amd64.deb

また、SlackのAPIはJSONファイルを扱うことが多いので、JSON整形用のコマンドを導入しました。

$ sudo apt install jq

最後にRTM APIを使うためのトークンを取得します。
一番手っ取り早いのはBotsインテグレーションの利用です。

https://[your_team_name].slack.com/apps/A0F7YS25R-bots

からSlackに追加をクリックし、ボットのユーザー名を入力するとトークン(xoxb-から始まる文字列)が表示されます。

実践

準備が整ったので早速APIを触ってみましょう。

まずはwebsocketでRTMを開始するためのURLを発行します。
詳細はrtm.connectを参照してください

# xoxb-***には取得したトークンを記述する
$ curl -X GET -H "Authorization: Bearer xoxb-*************" https://slack.com/api/rtm.connect | jq  

APIの結果はJSON形式で返ってくるのでjqで整形しています。
実行例は以下の通りです。

{
  "ok": true,
  "url": "wss://cerberus-xxxx.lb.slack-msgs.com/websocket/*****",
  "team": {
    "id": "****",
    "name": "your_team_name",
    "domain": "your_team_name"
  },
  "self": {
    "id": "*****",
    "name": "your_bot_name"
  }
}

このurlの値をもとに次のコマンドをすぐに実行します(30秒以内の制限あり)。

$ websocat wss://cerberus-xxxx.lb.slack-msgs.com/websocket/*****

ただ、30秒以内にURLをコピーしてwebsocatコマンドを実行するのは大変なので次のようにコマンドをまとめた方がよいかもしれません。

$ export SLACK_TOKEN="xoxb-******"
$ websocat $(curl -sS -X GET -H "Authorization: Bearer ${SLACK_TOKEN}" https://slack.com/api/rtm.connect | jq -r '.url')

成功すると

{"type": "hello"}

と表示されるはずです。

イベントを眺める

Slackクライアントからボットにダイレクトメッセージを送ってみましょう。ここではhogeというメッセージを送ってみました。

このときターミナル側では次のような出力が得られるはずです(一部マスクしています)。

{"type":"user_typing","channel":"*****","user":"******"}
{"client_msg_id":"******","suppress_notification":false,"type":"message","text":"hoge","user":"******","team":"******","blocks":[{"type":"rich_text","block_id":"tKU","elements":[{"type":"rich_text_section","elements":[{"type":"text","text":"hoge"}]}]}],"source_team":"******","user_team":"*****","channel":"*****","event_ts":"1583495285.002500","ts":"1583495285.002500"}
{"type":"desktop_notification","title":"*****","subtitle":"******","msg":"1583495285.002500","ts":"1583495285.002500","content":"hoge","channel":"******","launchUri":"slack:\/\/channel?id=******&message=1583495285002500&team=TCH2Q1N1H","avatarImage":"https:\/\/avatars.slack-edge.com\/****.png","ssbFilename":"knock_brush.mp3","imageUri":null,"is_shared":false,"is_channel_invite":false,"event_ts":"1583495286.000100"}

これらはSlackのイベントを表しています。
どうやらhogeというダイレクトメッセージを送った結果、3つのイベントが発生したようです。
どのようなイベントが発生したかは、typeの値を見ればわかります。

  • 1行目: typeuser_typingとなっています。このイベントは文字入力をしメッセージをているときに生じるイベントです (○○さんが入力しています みたいなメッセージが表示されることがありますよね)。
  • 2行目: typemessageになっています。文字通りメッセージが送られたことを表すイベントです。textの値も確かにhogeになっています。
  • 3行目: typedesktop_notificationです。

他にも様々なイベントが存在しここにまとめられています。

RTM APIでメッセージを送る

websocatの標準入力に文字を入力することでRTM APIを用いてメッセージを送ることができます。
ただしメッセージの送信はJSON形式で行います。

以下は入力例です。

{"type": "message", "channel": "******", "text": "foo"}

channelにはuser_typingmessageイベントで受け取ったchannelの値をそのまま入力します。

うまくいくとSlackクライアント側でfooというメッセージがボットに送られたことを確認できるはずです。

まとめ

websocetで直接RTM APIを叩いてみました。実際にボットを作るのであれば各言語で用意されているライブラリを使うべきでしょう。

現在推奨されているEvents APIではサブスクライブしたイベントだけがアプリサーバーに送られます。一方でRTM APIにはそういったスコープのようなものは無いです。

実際にRTMでイベントを受信するのを眺めてみると、スコープもなく様々なイベントが送られてくることが実感できますね!

  1. Classic AppもしくはBots インテグレーションで発行したトークンでRTM APIが利用できます。

  2. ただしRTM APIを使う場合、作成したSlackアプリの配布は出来ません。個人で活用する分には問題ないと思います。

10
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?