LoginSignup
1
4

More than 5 years have passed since last update.

Slackからメッセージ取得してShinyで表示してみる

Last updated at Posted at 2017-12-31

R言語のWebアプリ作成フレームワークShinyを使って、外部のWebAPIにアクセスするときのTipsです。
いろんなAPIと連携できるとRとShinyの表現力がより活かせますね。

今回はSlackからメッセージ履歴を取得してみます。

Slack側の準備

WebAPIを利用する場合、大体利用するシステム側でこういった準備が必要かと。不要な場合もありますが。

トークン取得

slack APIのページからトークン取得を行います。
レガシーなやつと新しいやつがありますが、今回はとりあえずレガシーなほうで。

こちらはAPIにアクセスするときに必要になるのでメモしておきましょう。

チャンネルIDの取得

指定のチャンネルのメッセージをとってくる場合、チャンネル名指定ではダメで、チャンネルIDが必要になります。
このIDがどこから取得していいかわかりにくいかったので、簡単な方法をメモ。
Web版のslackに移行し、該当ちゃんねるを開くと、URLにIDが出てきます。

image

エンドポイントの確認

利用したいアクションごとにURLが用意されているので、使いたいものを確認します。このページで必要なパラメータを確認します。
今回は特定のチャンネルのメッセージをとってこようと思うので、channels.historyを利用します。

おっと、期間指定がUNIX時間のようですね。

Shiny側のTips

パラメータ作成

まず、API側に送りつけるパラメータをlist形式で作成します。

image

Shinyの通常の構成としては画面側(ui.R)で入力部品を用意して、その入力の変化をトリガーにロジック側(server.R)の処理を動かします。

例えば、期間指定とトークンとチャンネルIDを受け取って、パラメータを作る場合は

ui.R
# サイドバーのところ
sidebarLayout(
  sidebarPanel(
    dateRangeInput(
      "date_range",
      "範囲選択",
      start = format(Sys.Date()-1, "%Y-%m-%d"),
      end = format(Sys.Date(), "%Y-%m-%d")
    ),
    textInput('token',"トークン"),
    textInput('channel',"チャンネルID")
  ),
  # MainPanel
  mainPanel(
     ###
  )
)
server.R
getVal <- function(obj){
  if(is.null(obj) || is.na(obj)){
    return("")
  }else{
    return(obj)
  }
}

endPoint.history <- 'https://slack.com/api/channels.history'

# slackへの送信パラメータ作成
getParams <- reactive({
  oldest = as.numeric(as.POSIXct(as.Date(input$date_range[1])))
  latest = as.numeric(as.POSIXct(as.Date(input$date_range[2])))
  token = input$token
  channel = input$channel

  params <- list(
    token = getVal(token),
    channel = getVal(channel),
    count = 1000,
    latest = latest,
    oldest = oldest
  )
  params
})

こんな感じ。

UNIX時間に変換する場合はPOSIXct型のものをas.numericで数値にすると大丈夫です。
また、入力を受ける場合reactiveである必要があるのでreactive({})で定義します。

URLからパラメータ取得

トークンなどをプログラム中に埋め込むのはいやなので、URLに引っ付けれるようにします。
http://xxx/shiny/?token=aaaaa
みたいなページを開くとトークンが設定されるようにしてみます。

URLの情報を取得したい場合は
session$clientDataから各種情報が取得できます。

?token=aaaaaを取得して、それをセットした状態でテキストボックスを生成するという場合、ui.R側にはuiOutput('name')を用意しておき、サーバー側でtextInput部品を生成します。

ui.R
#    textInput('token',"トークン"),
    uiOutput('tokenOut')
server.R
output$tokenOut <- renderUI({
    urlInfo <- parseQueryString(session$clientData$url_search)

    textInput('token',"トークン", urlInfo[["token"]])
})

APIアクセスとデータ取得

HTTPアクセス周りをサポートしてくれるhttrパッケージを入れておくと便利です。
こちらのPOSTメソッドを使ってアクセスします。上で作成したパラメータを渡して情報を取得します。

server.R
  getSlackData <- reactive({
    params <- getParams()

    resp <- POST(endPoint.history, 
                body = params,
                encode = "multipart",
                content_type = "application/x-www-form-urlencoded"
#                ,verbose() # コレつけるとリクエスト・レスポンスの詳細が見れる
                )
    jsonFromSlack <- content(resp, "parsed")
    # 取得した情報がlist形式に得られるのでここから自由に加工
  })

[翻訳] httr vignette: httrはやわかり

このあたりが抑えられれば、あとは通常のR&Shinyの書き方でグラフやら表やらを作っていくとWebアプリが出来上がりそうです。

とりあえず作ってみているサンプルソースコードはこちら

Slackはメッセージ自体に階層構造持たせたりできるので、そのあたりもうまく解析して必要なメッセージが取得できるような汎用性を持たせたい。

1
4
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
1
4