Slack分析で組織のコンディションを可視化する

こんにちは、HRBrainの川田です。

Slack分析した話を書きます。

# 背景
HRBrainには、リリースしたらみんなで祝う文化があります。

![Group 47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67253/42cf253f-df9a-682d-4936-39ce04ae8401.png)

なんとなく良い感じぽいな〜という印象はあるものの、組織全体として良い状態なのかは分かりません。

偉い人「最近の組織コンディションはどんな感じ？」
わたし「良い気がしますね」
偉い人「へえ〜、具体的には？」
わたし「活発というか元気があるというか」
偉い人「よく分からん」

全く同じではないにしても、これに近しいことは体験した方が多いんじゃないでしょうか。

我々HRBrainは、HR Techのドメインでプロダクトを作っている会社です。
ならば、HRをテックでハックしようじゃないか！
ということで、雰囲気ではなくデータで可視化することにしました。

# 何を定量化するか
組織コンディションを計測するために、以下の理由から今回はSlackを用います。
- 特定の職種に限らず、全従業員が等しく使うツールであること
- データをExportできるので、手軽に分析ができること
- Export対象はパブリックに投稿しているものだけであり、DMなどのクローズドな情報は対象外

事業環境の変化が大きい組織内では、様々な業務が自動化/仕組み化される前なので必然的にコミュニケーション量は多くなります。そのため、コミュニケーションツール上での発言量やリアクション数が少ないよりは多い方が組織コンディションは良いと言えそうです。

# Slack分析をしてみる
Slackでは、管理者以上の権限があればデータのExportが可能です。

期間はいくつか選択が可能で、今回は指定できる「Specific date range」を選びました。

半年~1年分のExportでだいたい30分程度かかるので、長年使っている会社でのEntire historyは避けた方がいいと思います。

![スクリーンショット 2023-07-09 20.17.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67253/5410be92-6d5d-1e33-61ec-dab15df50e8b.png)

Exportしたデータは、以下のような形でjsonで吐き出されます。

```
ディレクトリ構造
ORGANIZATION Slack export FROM DATE - TO DATE
├ CHANNEL NAME
│ └ YYYY-MM-DD.json
│ └ ...
├ ...
└ users.json
```
```json: YYYY-MM-DD.json
[
    {
        "client_msg_id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
        "type": "message",
        "text": "部長、そろそろ練習しましょう！",
        "user": "XXXXXXXXX",
        "ts": "1660819608.912249",
        "blocks": [
            {
                "type": "rich_text",
                "block_id": "XXXX",
                "elements": [
                    {
                        "type": "rich_text_section",
                        "elements": [
                            {
                                "type": "text",
                                "text": "部長、そろそろ練習しましょう！"
                            }
                        ]
                    }
                ]
            }
        ],
        "team": "XXXXXXXXX",
        "user_team": "XXXXXXXXX",
        "source_team": "XXXXXXXXX",
        "user_profile": {
            "avatar_hash": "XXXXXXXXXXXX",
            "image_72": "https:\/\/avatars.slack-edge.com\/2023-05-30\/XXXXXXXXXXXXX_72.png",
            "first_name": "Taro",
            "real_name": "Sample Taro",
            "display_name": "サンプル 太郎",
            "team": "XXXXXXXXX",
            "name": "Sample",
            "is_restricted": false,
            "is_ultra_restricted": false
        },
        "reactions": [
            {
                "name": "fire",
                "users": [
                    "XXXXXXXXX",
                    "XXXXXXXXX",
                    "XXXXXXXXX"
                ],
                "count": 3
            }
        ]
    },
    ...
]
```
```json: users.json
[
    {
    	"id": "XXXXXXXXX",
    	"team_id": "XXXXXXXXX",
    	"name": "Sample",
    	"deleted": false,
    	"color": "8f4a2b",
    	"real_name": "sapmple taro",
    	"tz": "Asia/Tokyo",
    	"tz_label": "Japan Standard Time",
    	"tz_offset": 32400,
    	"profile": {
    		"title": "XXX",
    		"phone": "080-XXXX-XXXX",
    		"skype": "",
    		"real_name": "sample taro",
    		"real_name_normalized": "sample taro",
    		"display_name": "サンプル 太郎",
    		"display_name_normalized": "サンプル 太郎",
    		"fields": {
    			"Xf03RWK3QKBM": {
    				"value": "XXX",
    				"alt": ""
    			}
    		},
    		"status_text": "",
    		"status_emoji": "",
    		"status_emoji_display_info": [],
    		"status_expiration": 0,
    		"avatar_hash": "XXXXXXXXXXXX",
    		"image_original": "https://avatars.slack-edge.com/2023-05-30/XXXXXXXXXXXXX_original.png",
    		"is_custom_image": true,
    		"huddle_state": "default_unset",
    		"huddle_state_expiration_ts": 0,
    		"first_name": "tanaka",
    		"last_name": "shota",
    		"image_24": "https://avatars.slack-edge.com/2023-05-30/XXXXXXXXXXXXX_24.png",
    		"image_32": "https://avatars.slack-edge.com/2023-05-30/XXXXXXXXXXXXX_32.png",
    		"image_48": "https://avatars.slack-edge.com/2023-05-30/XXXXXXXXXXXXX_48.png",
    		"image_72": "https://avatars.slack-edge.com/2023-05-30/XXXXXXXXXXXXX_72.png",
    		"image_192": "https://avatars.slack-edge.com/2023-05-30/XXXXXXXXXXXXX_192.png",
    		"image_512": "https://avatars.slack-edge.com/2023-05-30/XXXXXXXXXXXXX_512.png",
    		"image_1024": "https://avatars.slack-edge.com/2023-05-30/XXXXXXXXXXXXX_1024.png",
    		"status_text_canonical": "",
    		"team": "XXXXXXXXXX"
    	},
    	"is_admin": false,
    	"is_owner": false,
    	"is_primary_owner": false,
    	"is_restricted": false,
    	"is_ultra_restricted": false,
    	"is_bot": false,
    	"is_app_user": false,
    	"updated": 1685414059,
    	"is_email_confirmed": true,
    	"who_can_share_contact_card": "EVERYONE"
    },
    ...
]
```
そのままだと分析しづらいので、CSVに書き換えます。

https://github.com/ssossan/slack-analytics/

今回用いたカラムは以下です。
- display_name: Slackで表示されている名前
- name: ローマ字の名前（Slack上では表示されていないらしい）
- is_restricted: ゲストアカウントかどうか
- deleted: 無効化ユーザーかどうか
- day: 日付
- channel_name: Channel
- posts: 投稿数
- received_reactions: 絵文字リアクションをもらった数
- received_reaction_users: 絵文字リアクションをもらった人数
- given_reactions: 絵文字リアクション数を与えた数
- given_reaction_users: 絵文字リアクション数を与えた人数

対象者が日ごと、Channelごとに、どれだけ投稿したか、絵文字リアクションをもらったか、絵文字リアクションを与えたかが1行に表示されます。

# 可視化
CSVが吐き出せたので、可視化します。

可視化には、Googleが提供しているLooker Studioというツールを利用します。

![スクリーンショット 2023-07-10 0.33.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67253/7ea4bc50-9d3b-f5c0-c579-40606905101e.png)

Looker Studioは、無料で使える、様々なデータソースからポチポチだけで簡単にいろんな切り口で可視化できるBIツールです。

https://cloud.google.com/looker-studio?hl=ja

スプシやBigQueryなども使えますが、直接ファイルをアップロードすることもできるので、今回は作成したCSVをそのままアップロードして表を作ってみます。

### シンプルな表の作成

投稿が多い人を上から順に表示することができました！

![Group 46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67253/e85bae65-36d7-4125-a461-e70abb0bccda.png)

### 時系列の投稿数の推移

社内の全Public channel投稿数を、月ごとに並べることもできます。

![スクリーンショット 2023-07-12 13.04.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67253/1d6e6303-dda4-ee58-5dd5-bae8aea57e0e.png)

3月は期末だからいろいろ盛り上がって上がってたんだろうなとか、6月は夏が近づいてきてるからみんなテンション上がってるのかな、などいろいろ想像ができます。

実際はもっとちゃんとした仮説を立てましょう。

### とある新卒メンバーの投稿数/与えたリアクション数/もらったリアクション数の推移

ちなみに、2023年新卒エンジニアで急角度で成長している人は、このような推移でした。

![スクリーンショット 2023-07-10 1.29.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67253/4c330d0d-b288-b893-02ec-e0f2875294f8.png)

元々内定者アルバイトを週数日実施していたのですが、新卒正社員として動き出した4月からは発言数/与えたリアクション数/もらったリアクション数全てにおいて、稼働日数の増加率を上回る凄まじい伸びでした。

### もっと複雑な分析
それでは、もうちょっと複雑な分析をしてみましょう。

リアクションをたくさんした人、たくさんもらっている人の分布を見てみます。

![スクリーンショット 2023-07-12 11.18.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67253/88abef16-a7a3-1a93-2c98-c18baec14ecf.png)

Looker Studioのバブルチャートというグラフを使いました。一つの円は従業員を、円の大きさは投稿数を示しています。

X軸が、円の従業員が付けたリアクションの総数、
Y軸が、円の従業員がもらったリアクションの総数です。
また、円の大きさは投稿数を示しています。

右下は、自分からリアクションをたくさんしていて、もらったリアクションは少ないエリアです。このエリアに入っている人は、他者を応援する支援者的なキャラクターということが言えそうです。

左上は、もらったリアクションが多く、自分からはそれほどリアクションをしにいっていないエリアです。自分からは他者へ影響をそれほど与えないが、自身の振る舞いが他者に多くの影響を与えているキャラクターが多そうです。

右上は、自分からも他者からもリアクションが多いエリアです。
他者の応援もしながら、自身が他者へ大きな影響を与えている、社内で大きな影響を与えるキーマンと言えそうです。

# あなたのSlack Exportデータを可視化する
## 1. ExportデータをCSVに変換する
https://github.com/ssossan/slack-analytics/

上記repoをcloneして、ExportのデータからCSVを出力します。

```shell-session
$ go run converter.go DIRECTORY_PATH

DIRECTORY_PATH.csv  file created successfully.
```

## 2. CSVを、Looker Studioにインポートして可視化する
https://lookerstudio.google.com/u/0/reporting/39418dd3-b831-4141-b5ba-3f5eb7f808b3/page/ywgWD/edit

↑のページにテンプレートを作成しました。各自の環境にコピーして、以下の設定をしたら1で作成したCSVの内容でグラフが更新されます。

![pudate looker studio.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67253/deeeb4f0-a0a7-f9da-3456-b727def22758.gif)

ぜひ試してみてください！

# まとめ
本記事では、SlackのExport機能を用いて、組織のコンディションを可視化してみました。

同じCSVを使った分析でもまだまだいろんな切り口が考えられるでしょうし、CSVの吐き出し方ももっと様々考えられるはずです。

ぜひみなさんも各々の環境で可視化してみてください！

Exportは管理者以上の権限が必要なので、権限が無い方はこの記事を見せてExportを依頼すると良いと思います。Publicデータしか見れないので、懸念はほとんど無いはずです。

使えるけど意外と使ってなかった身近なデータを使って、組織の状況をより的確に把握し、次に活かしていくためのきっかけになったら嬉しいです。

おしまい。