あすけんSlackの人気絵文字ランキング

はじめまして!
askenのユウマと申します😊

shoku-pan🍞という名前でTwitterをやっています。
askenでは、MLエンジニアとして働いてます。
主に、画像処理や自然言語処理、データサイエンス周りを担当しています。
また、業務効率化のためのツールの作成や、ナレッジ共有のための社内勉強会を開いたりもしてます。
社外では、kaggleやatmaCupに参加したり、データサイエンティストの方達ともくもく作業したりと、ゆるゆると活動しています。

さて、先日以下のTweetが弊社のエンジニアの間で話題になりました。

最近よく目にする(気がする)この動く棒グラフは、「bar chart race」と呼ばれるものらしいですね。
Slack APIで、社内Slackの絵文字データを集計し、データを可視化するツールを使えばできるようです!
僕自身、Slack APIを使った経験はあまりなく、「Slackのデータを色々と分析できたら面白いだろうな」と思っていました。

弊社askenのSlackでもやってみたので、この記事で紹介します😊

目次

  • はじめに
  • 目次
  • 全体の流れ
  • セットアップ
    • Slack Appの作成
  • 実装
  • Bar chart raceの表示
  • 🎉結果発表🎉
  • まとめ
  • 参考資料

全体の流れ

まず、全体の流れは以下になります。

  • セットアップ
    • Slack Appの作成
  • 実装
    • Slackからメッセージ履歴を取得
    • 絵文字データを抽出・集計
    • csvファイルに出力
  • 可視化
    • Flourishにcsvファイルをインポート
    • bar chart raceの表示

セットアップ

Slack Appの作成

まず、Slackからデータを取得するために、Slack Appを作成します。 Slack Appの作成方法は、こちらの記事
Slack API | Web API から Slack App 経由で チャンネル履歴を取得する
を参考にしました。
ここで、Slack APIにどこまで権限を与えるか(スコープ)を決める必要があるのですが、今回は

  • channels:history
  • reactions:read

を指定しました。
※OAuth & Permissions > Scopes > User Token Scopes で設定できます。
スコープを指定してSlack APPを作成し、Slackのワークスペースにインストールできれば、いよいよ実装です!

実装

今回、言語はPython、環境はGoogle Colaboratoryを使用しました。
それでは、まずは設定です。

# Settings
TOKEN = '[token ID]'
CHANNEL = '[channel ID]'
NUMDAYS = 365 # データを取得する日数

ここで、[token ID]には
OAuth & Permissions > OAuth Tokens for Your Workspace > User OAuth Token
に記載されている文字列を指定します。
[channel ID]の確認方法は以下が参考になります。
Slack — APIに使う「チャンネルID」を取得する方法
※なお、これらは重要な情報なので、取り扱いに注意して下さい

NUMDAYSには、過去何日分のデータを取得するかを指定しています。
今回は1年分となる365日を指定しました。
※この値が大きいほど、データの取得には時間がかかります。

あらかじめ、必要なライブラリもインポートしておきます。

# Import libraries
import pandas as pd
import requests
import datetime

次に関数を定義します。

# Functions
def get_conversations_history(oldest_date, latest_date):
    """
    メッセージ履歴を取得する
    """
    url = "https://slack.com/api/conversations.history"
    headers = {"Authorization": "Bearer "+TOKEN}
    params = {
    "channel": CHANNEL,
    "limit": NUMDAYS,
    "oldest": oldest_date,
    "latest": latest_date,
    }
    response = requests.get(url, headers=headers, params=params)
    return response.json()
def count_emoji(conversations_history, df, date):
    """
    メッセージ履歴から絵文字をカウントする
    """
    for i in conversations_history['messages']:
        if 'ts' in i and 'reactions' in i:
            ts = i['ts']
            ts = datetime.datetime.fromtimestamp(int(ts.split('.')[0])) # unix時刻から標準時刻へ変換
            ts = ts.date() # 日付部分のみ取得
            reactions = i['reactions']
            for reaction in reactions:
                reaction_name = reaction['name']
                reaction_count = reaction['count']
                if reaction_name not in df.index:
                    df.loc[reaction_name] = 0
                df[date][df.index==reaction_name] += reaction_count

メインの処理は以下になります。

# Main
# 絵文字データをdataframeに格納
df=pd.DataFrame()
today = datetime.datetime.today()
# 今日の日付からNUMDAYS日前までのデータを取得。
# reversedで、日付の古い順に並び替え
for index, i in enumerate(reversed(range(0, NUMDAYS))):
    date_new = today - datetime.timedelta(days=i)
    date_old = today - datetime.timedelta(days=i+1)
    # Slack APIの時刻parameterはunix timeなので変換
    date_new_unix = date_new.timestamp()
    date_old_unix = date_old.timestamp()
    if index == 0:
        # df[date]に各絵文字の集計結果を格納する。カウント初日は0
        df[date_new.date()] = 0
    else:
        # df[date]に各絵文字の集計結果を格納する。前日の集計結果に足していく。
        df[date_new.date()] = df[date_old.date()]
        conversations_history = get_conversations_history(oldest_date=date_old_unix, latest_date=date_new_unix)
        if conversations_history['ok']: # responseが正しく返ってきた場合のみ処理実行
            count_emoji(conversations_history, df, date_new.date())
    
df # 結果確認

実行すると、以下のようなDataframeが出力されるはずです。
Slackの絵文字データがちゃんと集計されていますね!

f:id:techaskeninc:20210826174543p:plain

1日毎だとデータ量(カラム)が多すぎるので、1週間ごとに集計し直しました。
※カラムが多すぎると、この後Flourishにインポートしたときに全てのデータを表示することができませんでした。。

# Modify dataframe
df_result = df.copy()
df_weekly = pd.DataFrame()
for i in range(2, len(df_result.columns)):
    if i % 7 == 0:
        df_weekly[df_result.columns[i]] = df_result[df_result.columns[i]]
df_weekly

実行すると、以下のように出力されます。
今度は絵文字データが1週間単位(7日ごと)で集計されていますね!

f:id:techaskeninc:20210826174702p:plain

最後に、Dataframeをcsvファイルに出力しましょう。

# Output
df_weekly.to_csv('emoji_ranking_weekly.csv')

Bar chart raceの表示

ここまでで、Slackのデータを収集して絵文字データを集計し、結果をcsvファイルに出力するところまでできました。
では、このデータを使ってBar chart raceを表示してみましょう。
今回、Bar chart raceを表示するにあたっては、Flourishというサービスを使用しました。
こちらにアクセスしてください。
チュートリアルに従ってcsvファイルをupすれば、bar chart raceが表示されるハズです😉

🎉結果発表🎉

それでは、askenのSlackチャンネルの絵文字ランキングを発表します!
今回集計したデータは以下になります。

  • 全ての絵文字を集計(デフォルト絵文字およびカスタム絵文字)
  • generalチャンネル
  • リアクションとして使用された絵文字に限る(本文中で使用された絵文字は対象外)
  • 集計の期間は直近までの1年間
  • 上位15位を表示

直近1年間での集計の最終的なランキングは以下になりました🎉

順位 絵文字 絵文字名
🥇 tada
🥈 bows
🥉 done
4位 +1
5位 ok_hand
6位 ultra_fast_parrot
7位 asken2
8位 miki
9位 heart
10位 odaizini
11位 man-gesturing-ok
12位 woman-bowing
13位 nyan_parrot
14位 muscle
15位 sob

1位は🎉でした!新しいサービスのリリースやメディアでの紹介、また新入社員の紹介など、おめでたいことやテンションのあがる投稿に対するリアクションとして多く使われていました。
2位のは、「ありがとう」と感謝の気持ちをつたえる際に、3位のは依頼された作業を完了したときに使用されているようです。
また、7位には弊社サービス「あすけん」のロゴが、8位にはそのキャラクターの未来さんがランクインしていました。
これら2つはカスタム絵文字で、askenらしさがよく出た結果となりました😊

まとめ

いかがでしたか?

今回は、弊社askenのSlackの絵文字データを集計して、bar chart raceを表示してみました。
Slack APIを使用して、Pythonでデータを抽出・集計し、Flourishというサービスを使用することでつくることができます。

みなさんの会社でもやってみてはいかがでしょうか?
盛り上がること間違いなしだと思います!
ぜひ、皆さんの会社の絵文字ランキングも教えて下さいね

参考資料

自動化に対する取り組み

こんにちは。システム部の大澤です。 普段は北米版あすけんのiOSアプリを開発しています。

昨年の9月に入社して、もうすぐ、1年経とうしています。 iOSアプリの開発を担当し、1日の中でもたくさんの作業をしています。 その中で日々の作業の一部を自動化してきました。 その取り組みについてまとめました。 今回はとくにiOS開発以外にも活用できそうなものを中心にしました。

CI環境の整備

  • Bitriseを積極的に活用しました。
  • 毎回手動で作業するのは大変なので何度も作業するものはCIに任せました。

主な実行タスク

Task Trigger
ライブラリのアップデート 毎週火曜日の朝に1度、実行している
Dangerの実行 Pull Reqeustにpushしたとき
Unit Testの実行 Pull Reqeustにpushしたとき
git-pr-releaseを実行する developにマージしたとき
ライブラリのライセンスの更新チェック developにマージしたとき
Staging環境用のバイナリをアップロード developへpushしたとき
本番用のバイナリをApp Store Connectへアップロード masterにpushしたとき

Danger

  • Dangerとは
    • CIで実行して、Pull Requestのコードを解析して、ルールに合わせて、コメントをしてくれるツールです。
    • danger/danger
  • 主なルール
    • WIPがついている
    • Pull Requestにアサイン済みかのチェック
    • Merge可能か
    • ファイルがソートされているか
    • 作業内容に合わせて、GitHubのlabelを付与する
    • スペルミスがないかどうか
      • こちらは後ほど詳しく記載します
    • すべてパスするとLGTM画像が投稿される
  • 導入するとレビューで細かい指摘をしなくなり、本質的な部分を集中して、レビューすることができるようになりました。

f:id:techaskeninc:20210728151411p:plain

git-pr-release

  • x-motemen/git-pr-release
  • masterへマージする際にどの機能をマージしようとしているか一覧で把握できます。
  • Pull Reqeustのsummaryにリストで表示されます。
  • リグレッションテスト時に優先的にチェックする箇所を把握しやすくなった。
  • GitHubのリリースノート作成時にこのリストをそのまま再利用することもできます。

f:id:techaskeninc:20210728151506p:plain

cspell

  • streetsidesoftware/cspell
  • スペルミスをチェックするツールです。
  • 自分だけではスペルミスをすべて発見するのは難しいです。ツールを導入し、レビュー時にスペルミスをチェックする必要がほぼなくなりました。
  • Dangerと一緒に使うことでPull Reqeust時に気がつくことができる。
  • 導入段階ですでにコードにあるスペルミスを直すのが大変でした😅

App Store Connectの審査状況の通知

  • 審査状況の通知はメールやApp Store Connectのアプリで受け取ることができますがチームのメンバー全員がその環境を設定するのは大変です。
  • こちらの記事を参考に導入しましたiOSアプリの審査状況変更を、Slackに自動通知する(GAS + Slack Webhook)
  • 申請、リジェクト、リリースの通知を自動でSlackに投稿するので審査状況のチェックという作業がなくなりました。

f:id:techaskeninc:20210728151557p:plain

意識したこと

  • 導入段階で他のプロジェクトでもすぐに導入できる形にしておく。
    • ドキュメントは最小限にして、インストールや実行コマンドは手順をスクリプトにしておく。その結果、手軽に試すことができ、新しく関わる人に説明する時間を削減できる。
    • Makefileシェルスクリプトを活用して、よく使うコマンドはまとめた。
  • とりあえず試してみる。
    • 試してみて、必要だとわかることが多くありました。 実際に導入してみましたが、活用されず、廃止されたものもあります。

今後やってみたいこと

  • 今後は、Swaggerのようなドキュメントからコードを自動で生成するツールなどを導入して、実装コストの削減をやっていきたいです。その仕組みをiOS以外にも展開していきたいです。

まとめ

入社して、約1年でやってみたことをまとめてみました。一度導入してしまえば、長期的に作業時間の削減に貢献します。 さらに、iOS開発だけでなく、他の開発でも使えるものを積極的に導入できました。 まだ、自動化できる作業は残っているので今後も挑戦していきたいです。 askenでは、一緒に働いてくれるiOSエンジニアを募集しています。少しでも興味を持っていただけたら、ぜひ採用情報をご確認ください。

askenテックブログはじめます!

皆さん、はじめまして〜!
株式会社askenのシステム部にて部長をしている服巻です。


コロナのワクチン接種を約1ヶ月後に控え、「接種後も全然平気だよ」と「めっちゃ腕痛くなるよ」という接種した社内メンバーの声に気持ちを翻弄されている今日この頃です。

 

さて、今日はそんな僕のほうから告知があって本記事を書いているわけですが、何かというとaskenエンジニアによる公式ブログを始めるよ!って告知ですー!

 

その記念すべき最初の記事ということで、弊社サービスの紹介を少し。
弊社は、食事改善アプリ「あすけん」を国内外に展開・運営しています。

「ひとびとの明日を今日より健康にする」をミッションとし、ユーザーへ提供する価値を最大限にするべく、日々、様々な課題に対してチームで果敢にチャレンジしています。

 

思い返せば8年前の11月、冬の足音が聞こえてきそうな中、そのaskenに僕は入社しました。当時、エンジニアは僕だけの1人システム部でしたが、今では優秀で個性豊かな仲間たちが集まってくれて、12名の愉快な仲間たちになりました。(ホント嬉しい!)


メンバーが増えるたびに新たな価値観が混ざり芽生え、各人、各チームが主体的に学ぶ姿勢をもって成長してくれる文化ができつつあります。このブログでは、そんな彼らの取り組みを少しでも周りに知ってほしい!へ〜って思ってほしい!ときに笑ってもほしい!と個人的に思っています。


組織的には、このブログを通じてaskenエンジニアが日々どんなことに取り組んでいるかを皆さんに少しでも知ってもらえる機会になればいいなと思っていますし、記事にすることによって各人がそれぞれのテーマについてより深い学びに繋がってくれることも期待してたりします。

 

さてさて、今後どんなテーマで発信されていくのやら楽しみでしかありません!!
皆さんも一緒に「askenテックブログ」を楽しみにしてくれる事を願っています!!!