はじめまして、こんにちわ。
#はじめに
Slack Advent Calendar7日目、初めてアドベントカレンダーに参加します。
ちょうど1年前に、2018年に一番使われたSlackの絵文字を調べるアプリケーションを作りました。その内容を記事にしようと思ってほったらかしにして1年が過ぎました。1年でSlackのAPIも結構変わりましたので、最新の仕組みに乗っかるように作り替えてみます。
##作ったもの
こんなメッセージを送るApp(Bot)です。
期間を1年に設定すれば年間ランキングが作れます。
毎週月曜日に送るようにすると、先週に頑張った人が見えるようになります。
Botと言っても現状はSlashコマンドの実装はしていなく、普通のPHP(Laravel)のスタンドアロンアプリケーションです。
##使ったもの
- Slack API
- Laravel Framework 6.6.0
- Guzzle 6.4
今回もWindows環境です。
#まず、作戦会議
まず、リアクションの捕まえ方を調べます。
##会話データからリアクションのとらえ方
conversations.history
を叩いて、APIの結果を眺めてみます。
{
"ok": true,
"latest": "1585158399.000000",
"oldest": "1546300800.000000",
"messages": [
{
"client_msg_id": "7c0272bf-4222-46b3-b10d-9bc5ca8a9d37",
"type": "message",
"text": "\u306f\u308d\u30fc",
"user": "UNUGXMXQQ",
"ts": "1575207922.000600",
"team": "TDWRKFV0S",
"blocks": [
{
"type": "rich_text",
"block_id": "p1411",
"elements": [
{
"type": "rich_text_section",
"elements": [
{
"type": "text",
"text": "\u306f\u308d\u30fc"
}
]
}
]
}
],
"reactions": [
{
"name": "grinning",
"users": [
"UDX2143CM"
],
"count": 1
},
{
"name": "grin",
"users": [
"UDX2143CM",
"UNUGXMXQQ"
],
"count": 2
},
(省略)
]
},
messages
という配列の中にmessage
のオブジェクトがあり、これが1つ分の発言(チャットのポスト)を表現しています。メッセージにリアクションが付くと、messageの中のreactions
という配列が設定されます。reactions配列には、リアクションアイコンのオブジェクトが入っていて、さらにその中にリアクションをしたユーザIdがusers
の配列に入っている形です。
メッセージの送信主がmessage.user
でとれるので、message.user
をリアクションの受信者(TO)とし、reaction.usersをリアクションを送った人(FROM)として関係性を積み上げていけばよさそうです。
上のサンプルでいうと、以下のような表にまとめればいいわけです。
from | to | icon |
---|---|---|
UDX2143CM | UNUGXMXQQ | |
UDX2143CM | UNUGXMXQQ | |
UNUGXMXQQ | UNUGXMXQQ |
UNUGXMXQQ
さんが投げたメッセージに対し、UDX2143CM
がのリアクションをし、UDX2143CM
さんとUNUGXMXQQ
さんがのリアクションをしたので、以下のような関係になります。自分から自分のリアクションもあり得るので、そこは集計時に考慮しましょう。
##ユーザIDからユーザ名への変換
SlackのAPIはユーザIDを返すので、これでサマリーしても誰のことだかわからないです。今回はいったんSlackの全ユーザを取り出してIDから名前に変換する処理をしています。ユーザ数が多いときはちょっと考慮が必要になりそうです。
#環境準備
では、今回の環境を作ります。
##開発環境の準備
laravelの最新版を入れて、Guzzleパッケージのインストールし、laravelのコマンドラインクラスを作るところまで。
> cd \
> mkdir reactionman
> cd reactionman
> composer create-project laravel/laravel --prefer-dist .
(省略)
Application key set successfully.
> composer require guzzlehttp/guzzle
Using version ^6.4 for guzzlehttp/guzzle
(省略)
Package manifest generated successfully.
> php -v
PHP 7.2.11 (cli) (built: Oct 10 2018 02:39:52) ( ZTS MSVC15 (Visual C++ 2017) x86 )
> php artisan -V
Laravel Framework 6.6.0
> php artisan make:command ReactionMan\ReactionManStart
Console command created successfully.
C:\reactionman\app\Console\Commands\ReactionMan
にPHPのファイルができていればOK。
##Slack Appの設定
ReactionManを新規のAppとして作ります。
https://api.slack.com/
右上のYourAppをクリック
https://api.slack.com/apps
Create New App をクリック
OAuthのメニューでAppのスコープを追加しておく。
channels:history, channels:read, chat:write:bot, users:readの4つのスコープを追加します。
Install App to Workspaceでアプリの登録を忘れずに。
ここまでで準備完了です
#プログラムを作る
今回はLaravelのCommandインターフェイスでバッチプログラムを作りました。4ファイルだけなのでgithubにあげときます。 https://github.com/kanaxx/reactionman
以下のようなことをやっています。
- 引数のチェック
- Slackの全チャンネルデータを取得
- Slackの全ユーザデータを取得
- 指定のチャンネルの会話データを取得
- 会話の中のリアクションを集計
- 集計結果をBlock Kitの形式に変換
- 結果をSlackにPOST
#リアクションマンの使い方
--help
で使い方が出ます。Laravel賢い
> php artisan reactionman:start --help
Description:
Slackのリアクションを集計してレポートするかわいいやつ
Usage:
reactionman:start [options]
Options:
--days[=DAYS] 集計日数
--start[=START] 集計の開始日 2019-11-11形式
--end[=END] 集計の終了日 2019-11-11形式
--channel[=CHANNEL] 集計対象チャネル(publicのみ)
--sendto[=SENDTO] 通知先チャンネル名(publicのみ).指定がないときは結果をPostしないで終わる
--token[=TOKEN] 結果をpostMessage可能なユーザトークン
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
--env[=ENV] The environment the command should run under
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
##使い方
こんな感じで叩くといいでしょう。
#過去7日間のchannel2のリアクションを集計してgeneralチャンネルに送る
php artisan reactionman:start --days=7 --channel=channel2 --sendto=general --token=xoxp-xxx
#2019年のchannel2のリアクションを集計してchannel2送る
php artisan reactionman:start --start=2019-01-01 --end=2019-12-31 --channel=channel2 --sendto=channel2 --token=xoxp-xxx
##パラメータの説明
###トークン
全部のSlack APIに使うトークン。ボットトークンだとconversations.historyができないのでユーザトークンが必要。
###期間の指定
過去7日分の集計の場合は --days=7
期間を指定するときは、--start=2019-11-01
と--end=2019-12-01
のように指定
両方指定するとdaysのほうが優先されます。
###調べるチャンネル
--channel=チャンネル名
で指定。チャンネルIDを調べなくてOK
###結果を送るチャンネル
--sendto=チャンネル名
で指定。こちらもチャンネルIDでなくてOK。sendtoが指定されないとき、もしくは指定されたチャンネルが存在しないときは、集計はするけど送信はしない。
#まとめ
Slackが推奨する気軽なコミュニケーションがどれくらい使われているのかが分かるようになります。一年でどれだけ絵文字が飛び交ったのか、確認してみてはいかがでしょうか。
複数チャンネルの集計をできるようにすると、会社全体の絵文字ランキングが作れますね。