share facebook facebook2 twitter menu hatena pocket slack

2017.03.09 THU

Slackで使われている絵文字ランキングを作る

WRITTEN BY 齊藤 愼仁

シンジです。cloudpackのSlackチームも使い始めてだいぶ経ちましたし、絵文字の利用も活発なので、実際のところどんな絵文字がよく使われているのか気になりました。というわけでランキングの作成です。

結果こんなかんじです

どうやるか

ちょっとハードルが高い部分もあるので、要確認です。流れはこんなかんじ。

1.Slackのメッセージエクスポート機能で、過去のメッセージ全てをダウンロードする(管理画面にしかないのでAdmin権限以上が必須)

2.ダウンロードしたファイルから絵文字部分を抽出してカウントする

3.サンシャイン池崎

Slackからメッセージをダウンロードする

下記URLにAdmin権限以上でアクセスします。

Slack Export Data
https://slack.com/services/export

で、Startボタンぽちー。

ここでダウンロードできるメッセージは、Adminのあなたがアクセスできるメッセージの全てをダウンロードできます。つまり、あなたがアクセスできない他人のダイレクトメッセージや、あなたの参加していないプライベートチャンネルはダウンロードされません。結果的には、絵文字の集計にはこれらのアクセスできないチャンネルは含まれない形となります。

そこも厳密に取らせろという猛者がおられるのであれば、Owner権限でコンプライアンスエキスポートをすることで、真の意味での全メッセージをダウンロードできますが(しかも結構面倒)、プライバシーの問題もあるので慎重にどうぞ。

処理にしばらく時間がかかります

10分くらいです。が、Slack-botで通知が来ますので、しれっと待ちましょう。

ではダウンロードします。ZIPで落ちてきます。

ダウンロードしたファイル、解凍してみましょうか

チャンネルごとのディレクトリ、大量のJSONファイルを確認できましたか?

JSONの中身を見てみて下さい。空前絶後のJSONです。人間が読むファイルではありません。

というわけでプログラム的に処理してやります。

今回はJavaScriptで

ファイル名は何でもいいです。slack-emoji-ikezaki.jsとかでいいです。
下のコードはググりまくってどっかのWebから拾ってきたのですが、もはや記憶障害でどこから拾ったのか覚えていないのでそこはもう勘弁して下さい。

"use strict";

var fs = require("fs");
var path = require("path");

var dir = "export";

let count = fs.readdirSync(dir)
  // we only want channel sub-directories
  .filter(file => fs.statSync(path.join(dir, file)).isDirectory())
  .reduce((a, subdir) => a.concat(
      // read sub-directory
      fs.readdirSync(path.join(dir, subdir))                                   
        // parse each logfile  
        .map(file => JSON.parse(fs.readFileSync(path.join(dir, subdir, file))))
    ), [])
  // flatten array of array of messages
  .reduce((a, b) => a.concat(b), [])                               
  // keep only messages with text property and not bots!              
  .filter(msg => msg.user && msg.type == "message" && !msg.subtype)
  // count occurences for each emoji
  .reduce((count, msg) => {
    (msg.text.match(/:([a-z0-9_]+):/g) || [])
      .forEach(emoji => count[emoji] ? count[emoji]++ : count[emoji] = 1);
    return count;
  }, {});

// print top list
Object
  .keys(count)
  .sort((a, b) => count[b] - count[a])
  .forEach(emoji => console.log(`${emoji} ${count[emoji]}`));

Slackのログデータのフォルダ名をexportに変えておきます

exportフォルダと同じ場所にikezaki.jsをおいて下さい。

JavaScriptなのでWinでもMacでもLinuxでも動きますが

結果的には今回のログデータがでかすぎて、メモリ35GBは食うし、CPU唸るので、手元のマシンじゃピャーだったのでAWSでAmazonLinuxをGOしました。

インスタンスは、とりあえず一番いいやつ(ぇ

node使いたかったので、AmazonLinuxに環境を用意します。まずはnvmから。

sudo yum install git
git clone https://github.com/creationix/nvm.git ~/.nvm && cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`
source ~/.nvm/nvm.sh

次にnode.jsをぶち込みます。最新バージョンはどれかにゃ?ってことで調べます。

nvm ls-remote

先日7.6.0がリリースされたので、早速インストールです。

nvm install v7.6.0

実行環境は楽勝で構築完了。

Slackのログデータもろもろをscpなりで転送

してください。ZIPはunzipで解凍です。
で、実行ですが、実行結果の出力も明示的に書いてやります。

node ikezaki.js > sekaiheiwa.log

そうするとこんな感じのログファイルが

30分くらいかかって作成されます。鬼インスタンス使って30分もかかるとか。もうやりたくない。

:bow: 5956
:pray: 3808
:zumi: 3331
:kaien: 3254
:00: 2776
:haisho: 2674
:puke: 2609
:kan: 2379
:go_center: 1987
:go_rev: 1737
:space: 1675
:aws: 1645
:iine: 1337

これ、そのままSlackに貼れば絵文字も出力されるのですが、ちょっと味気ないので、Google Spreadsheetで見た目だけ整えました。

割と雑

というわけで

すだちくんが後藤さんよりも上位だったので大満足です

元記事はこちら

Slackで使われている絵文字ランキングを作る

齊藤 愼仁

cloudpack 社内インフラ担当、情報セキュリティ責任者。HPCを経て現職に至る。無類の猫好きで、すだち君という名の猫を飼っている。