R言語のWebアプリ作成フレームワークShinyを使って、外部のWebAPIにアクセスするときのTipsです。
いろんなAPIと連携できるとRとShinyの表現力がより活かせますね。
今回はSlackからメッセージ履歴を取得してみます。
Slack側の準備
WebAPIを利用する場合、大体利用するシステム側でこういった準備が必要かと。不要な場合もありますが。
トークン取得
slack APIのページからトークン取得を行います。
レガシーなやつと新しいやつがありますが、今回はとりあえずレガシーなほうで。
こちらはAPIにアクセスするときに必要になるのでメモしておきましょう。
チャンネルIDの取得
指定のチャンネルのメッセージをとってくる場合、チャンネル名指定ではダメで、チャンネルIDが必要になります。
このIDがどこから取得していいかわかりにくいかったので、簡単な方法をメモ。
Web版のslackに移行し、該当ちゃんねるを開くと、URLにIDが出てきます。
エンドポイントの確認
利用したいアクションごとにURLが用意されているので、使いたいものを確認します。このページで必要なパラメータを確認します。
今回は特定のチャンネルのメッセージをとってこようと思うので、channels.historyを利用します。
おっと、期間指定がUNIX時間のようですね。
Shiny側のTips
パラメータ作成
まず、API側に送りつけるパラメータをlist形式で作成します。
Shinyの通常の構成としては画面側(ui.R)で入力部品を用意して、その入力の変化をトリガーにロジック側(server.R)の処理を動かします。
例えば、期間指定とトークンとチャンネルIDを受け取って、パラメータを作る場合は
# サイドバーのところ
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(
###
)
)
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部品を生成します。
# textInput('token',"トークン"),
uiOutput('tokenOut')
output$tokenOut <- renderUI({
urlInfo <- parseQueryString(session$clientData$url_search)
textInput('token',"トークン", urlInfo[["token"]])
})
APIアクセスとデータ取得
HTTPアクセス周りをサポートしてくれるhttrパッケージを入れておくと便利です。
こちらのPOSTメソッドを使ってアクセスします。上で作成したパラメータを渡して情報を取得します。
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形式に得られるのでここから自由に加工
})
このあたりが抑えられれば、あとは通常のR&Shinyの書き方でグラフやら表やらを作っていくとWebアプリが出来上がりそうです。
とりあえず作ってみているサンプルソースコードはこちら。
Slackはメッセージ自体に階層構造持たせたりできるので、そのあたりもうまく解析して必要なメッセージが取得できるような汎用性を持たせたい。