Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
24
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

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

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リクエスト/秒)にひっかかりやすくなるのでご注意ください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
24
Help us understand the problem. What are the problem?