30
23

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 5 years have passed since last update.

Slack APIで「いいね!」リアクションを集計するシェルスクリプト

Last updated at Posted at 2015-09-03

Slack APIで「いいね!」リアクションを集計するシェルスクリプト

動機

社内でも利用しているチャットツールSlackで2015年7月9日からメッセージに絵文字リアクションがつけられるようになりました。

「Slack」に投票や参加表明に使える絵文字利用の新ツール「Emoji Reactions」 - ITmedia ニュース

絵文字リアクションを使ってお互いに「いいね!」というイイ感じの文化が生まれてきたので、さらなる活性化を目論んで、全員が参加するチャンネルで一番「いいね!」のリアクション(+1またはthumbsup)を獲得しているメッセージをSlack APIを使って集計して報告する仕組みをcron+シェルスクリプトで作ってみました。

準備

まず、Slack APIで使うトークンを以下のページから取得してきます。

Slack Web API | Slack

また、集計するチャンネル・報告するチャンネルのIDが必要なので、以下のページからIDを確認します。

channels.list method | Slack

cron+シェルスクリプトを実行するLinuxマシンを用意します。以下のものをインストールします。curlとjqにパスが通っているか確認してください。

  • cron
  • curl
  • jq

シェルスクリプト

以下のスクリプトをcronで一日一回実行するようにします。

#!/bin/bash

# 作業用の一時ファイル格納先を設定します
MY_WORKSPACE=/tmp

# 取得したトークンを設定します
MY_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# 集計対象のチャンネルのID・名称を設定します
MY_CHANNEL=yyyyyyyyy
MY_CHANNEL_NAME=all
# 集計対象の期間はスクリプト実行時の前日になります
MY_DATE=$(date +"%Y年%m月%d日" --date "1 day ago")
MY_LATEST=$(date +"%s" --date "$(date +"%Y-%m-%d 00:00:00")")
MY_OLDEST=$(date +"%s" --date "$(date +"%Y-%m-%d 23:59:59" --date "2 day ago")")

# 集計結果を報告するチャンネルのIDを設定します
MY_POST_CHANNEL=zzzzzzzzz

# 前日のメッセージを取得してファイルに保存します
\rm -f ${MY_WORKSPACE}/my_history_${MY_CHANNEL_NAME}.json
curl -s -F token=${MY_TOKEN} -F channel=${MY_CHANNEL} -F latest=${MY_LATEST} -F oldest=${MY_OLDEST} https://slack.com/api/channels.history > ${MY_WORKSPACE}/my_history_${MY_CHANNEL_NAME}.json

# 変数初期化
MY_TOP_LINK=
MY_TOP_COUNT=0

while :
do
  # 取得したメッセージごとに処理
  for i in $(cat ${MY_WORKSPACE}/my_history_${MY_CHANNEL_NAME}.json | jq -r '.messages[].ts'); do
    # APIの実行制限回避のために1秒スリープします
    sleep 1
    # メッセージのリアクションを取得してファイルに保存します
    \rm -f ${MY_WORKSPACE}/my_reactions_get_${MY_CHANNEL_NAME}.json
    curl -s -F token=${MY_TOKEN} -F channel=${MY_CHANNEL} -F timestamp=${i} https://slack.com/api/reactions.get > ${MY_WORKSPACE}/my_reactions_get_${MY_CHANNEL_NAME}.json
    # リアクションから:+1:または:thumbsup:の数を取得します
    MY_TMP_COUNT=
    MY_TMP_COUNT=$(cat ${MY_WORKSPACE}/my_reactions_get_${MY_CHANNEL_NAME}.json | jq '.message | select(has("reactions")).reactions[] | select(.name=="+1" or .name=="thumbsup").count')
    # 最大数を更新します
    if test -n "${MY_TMP_COUNT}" ; then
      if test ${MY_TMP_COUNT} -gt 0 -a ${MY_TOP_COUNT} -lt ${MY_TMP_COUNT} ; then
        MY_TOP_LINK=$(cat my_reactions_get_${MY_CHANNEL_NAME}.json | jq -r '.message.permalink')
        MY_TOP_COUNT=${MY_TMP_COUNT}
      elif test ${MY_TMP_COUNT} -gt 0 -a ${MY_TOP_COUNT} -eq ${MY_TMP_COUNT} ; then
        MY_TOP_LINK="${MY_TOP_LINK}
$(cat ${MY_WORKSPACE}/my_reactions_get_${MY_CHANNEL_NAME}.json | jq -r '.message.permalink')"
      fi
    fi
  done

  # メッセージに続きがなければ終了します
  if test "$(cat ${MY_WORKSPACE}/my_history_${MY_CHANNEL_NAME}.json | jq '.has_more')" != "true" ; then
    break
  fi

  # メッセージに続きがあれば続きを取得します
  MY_TMP_OLDEST=$(cat ${MY_WORKSPACE}/my_history_${MY_CHANNEL_NAME}.json | jq -r '.messages[].ts' | tail -n1)
  \rm -f my_history.json
  curl -s -F token=${MY_TOKEN} -F channel=${MY_CHANNEL} -F latest=${MY_TMP_OLDEST} -F oldest=${MY_OLDEST} https://slack.com/api/channels.history > ${MY_WORKSPACE}/my_history_${MY_CHANNEL_NAME}.json
done

# 報告するメッセージをファイルに準備します
\rm -f ${MY_WORKSPACE}/my_post_message_${MY_CHANNEL_NAME}.txt
if test ${MY_TOP_COUNT} -gt 0 ; then
  echo "${MY_DATE}のベスト:+1:獲得数 in #${MY_CHANNEL_NAME}: ${MY_TOP_COUNT}
${MY_TOP_LINK}" > ${MY_WORKSPACE}/my_post_message_${MY_CHANNEL_NAME}.txt
else
  echo "${MY_DATE}のベスト:+1:獲得数 in #${MY_CHANNEL_NAME}: 0" > ${MY_WORKSPACE}/my_post_message_${MY_CHANNEL_NAME}.txt
fi

# 報告するメッセージを送信します
curl -s --data-urlencode token=${MY_TOKEN} --data-urlencode channel=${MY_POST_CHANNEL} --data-urlencode text@${MY_WORKSPACE}/my_post_message_${MY_CHANNEL_NAME}.txt --data-urlencode username=reaction_report --data-urlencode as_user=false --data-urlencode icon_emoji=:+1: --data-urlencode unfurl_links=true https://slack.com/api/chat.postMessage >/dev/null 2>&1

実行結果

報告メッセージがこんな感じになります。

fig01.png

注意点

メッセージごとにリアクションを取得するAPIを実行するので、メッセージ数が多くなると集計が遅くなるのと、APIの実行制限(1リクエスト/秒)にひっかかりやすくなるのでご注意ください。

30
23
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
30
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?