Slack API を使って、特定のチャンネルのメッセージと発言ユーザーを取得する #slack

概要

Slack の発言を分析したいみたいな話が職場であって、サクッと取れないかな〜と雑にシェルスクリプトで試してみた記録。

便利なツールとか既にありそうだけどね。。

  • Slack API を使って
  • 特定のチャンネルから一定期間の発言を取得し
  • 「投稿日時」
  • 「その発言をしたユーザー」
  • 「メッセージへのリンクURL」
  • を出力するまでの流れ

APIを叩く準備

Slack API を叩くには Token を発行する必要がある。

Token 単体では発行できなくて、アプリケーションを作成してインストールする流れになるようだ。

主な流れは下記の通り。

  1. Slack Application を作成
  2. Application に対して API を叩くのに必要な Scope を設定
  3. Token を発行
  4. Application を使いたい Slack Team にインストール

下記の記事がとても参考になった。

tearoom6.hateblo.jp

メッセージの取得

conversations.history を使う。

conversations.history method | Slack

Tester タブから実際にリクエストを試せるので便利。

slack_message_list.bash みたいなのを作ってみる。

  • jq を使って必要な情報だけ取り出す
    • ユーザーIDと投稿日時
  • 取得上限はデフォルト100件だが最大の1000にしている
    • LIMIT パラメータ
    • 1000件以上は考慮していない
  • 取得範囲を 2021-01-01 以降にしてる
    • OLDEST パラメータ
#!/usr/bin/env bash

set -eu

readonly API_TOKEN="xxxx-xxxxxxxxx-xxxx"
readonly CHANNEL="C1234567890"
readonly LIMIT=1000

# Unixtime に変換し、小数点配下を埋め。 ※Mac でやったので BSD の date コマンド
readonly OLDEST="$(date -j -f "%Y-%m-%d %H:%M:%S" "2021-01-01 00:00:00" +%s).000000"

## API を叩き、 jq で user と ts だけ抽出してカンマ区切りにする
curl -s "https://slack.com/api/conversations.history?channel=${CHANNEL}&oldest=${OLDEST}&limit=${LIMIT}" \
     -H "Authorization: Bearer ${API_TOKEN}" \
     -H 'Content-Type: application/json; charset=utf-8' \
  | jq -r '.messages[] | [.user, .ts] | @csv'

exit 0

ユーザー情報とメッセージへのリンクURLを取得

ユーザーIDを元にユーザー名、投稿日時を元にメッセージへのリンクURLを取得する。

ユーザーの取得には users.info を使う。

users.info method | Slack

メッセージへのリンクURLの取得には chat.getPermalink を使う。

chat.getPermalink method | Slack

conversations.history で取得した値を連携するような slack_user_link.bash を作成する。

#!/usr/bin/env bash

set -eu

readonly API_TOKEN="xxxx-xxxxxxxxx-xxxx"
readonly CHANNEL="C1234567890"

arg=${1}

# 受け取った値を分解して、不要なクォーテーションを除去
user_id=$(echo ${arg} | cut -d',' -f 1 | sed 's/"//g')
ts=$(echo ${arg} | cut -d',' -f 2 | sed 's/"//g')

## users.info
user_name=$(curl -s "https://slack.com/api/users.info?user=${user_id}" \
     -H "Authorization: Bearer ${API_TOKEN}" \
     -H 'Content-Type: application/json; charset=utf-8' \
     | jq -r .user.name)

## chat.getPermalink
url=$(curl -s "https://slack.com/api/chat.getPermalink?channel=${CHANNEL}&message_ts=${ts}" \
     -H "Authorization: Bearer ${API_TOKEN}" \
     -H 'Content-Type: application/json; charset=utf-8' \
      | jq -r .permalink)

# 投稿日時を表示用に変換
date=$(echo ${ts} | cut -d'.' -f 1 | xargs -I@ date -r @ +"%Y-%m-%d %H:%M:%S")

# カンマ区切りで表示
echo "${date},${user_name},${url}"

exit 0

組み合わせて実行してみる

↓な感じで組み合わせて実行できる。

./slack_message_list.bash | xargs -I@ ./slack_user_link.bash @

最初のスクリプト"U012AB3CDE","1512085950.000216" みたいなのを出力するので、それを元に次のスクリプトAPI を順繰り叩く感じ。

最終的な出力は↓みたいになる。

2021-01-19 10:47:21,user_a,https://ghostbusters.slack.com/archives/C1H9RESGA/p135854651500008
2021-02-18 10:43:24,user_b,https://ghostbusters.slack.com/archives/C1H9RESGA/p135854651500009
2021-03-17 12:55:30,user_c,https://ghostbusters.slack.com/archives/C1H9RESGA/p135854651500000

その他参考

unixtimeとdatetimeを変換する(Mac/BSD編) - Qiita