PythonとBigQueryを使って社内向けピアボーナスツール(集計のみ)を作った


はじめに

社員間で感謝や労いを送り合うツールといえばuniposなんかが有名ですが、
会社規模的にサービス導入は負担が大きいのでとりあえずそれっぽいものを作ってみることにしました。

やりたいこと

slackで専用チャンネルを作り、そこでメンション+メッセージを飛ばすとカウントされる。
月ごとに集計されて、可視化&MHP(モスト・褒められた・パーソン)を出す。
送られたメッセージもユーザーごとにまとめておきたい。

使ったもの

  • slack
    • 全社員が使用しているため採用
  • python slackbot
    • もともと社内で使っていたので採用
  • BigQuery
    • 集計と可視化のために利用
  • GAS
  • google データポータル

作成手順

slackの設定

まずslack apiで新しいBOTを作成します。

  1. Create New App をクリック
  2. App Name を入力して、 Workspace を選択してCreate App
  3. 今回はBOTとして使いたいのでBotsを選択
  4. Always Show My Bot as Online を ON
  5. OAuth & Permissions で Tokenを発行、slackbotから書き込むときに使うのでローカルにコピペしときます
  6. slackで褒め専用チャンネルを作成して、そこに作ったappを追加

これでslack側の準備はほぼ終わりです。お好みでappにアイコン設定したりしてください。

Google Spread SheetとGASの設定

後々非エンジニアが運用するかもしれないことを考え、今回はGET叩いたらSpread Sheetに書き込まれるようにしました。

感謝・労いをした人、された人、した人からのメッセージ、した日付の4カラムを保存します。

こちらのソースを流用させていただきました。

会社のsuiteを使ったため、
Execute the app as:をmeに、
Who has access to the app: を anyone にしないと権限の関係で書き込めませんでした。

できたURLを叩いて各カラムに書き込まれているのを確認して次に進みます。

Bigqueryとデータポータルの設定

先ほど作ったspreadsheetをデータソースとして読みこむプロジェクトを作成。
bigqueryの機能を使って可視化することも考えましたが、
操作が直感的なのでデータポータルを使用。

slackbotの設定

今回一番コーディングらしいコーディングをしたところ。

import requests
import datetime
import re
from slackbot.bot import listen_to
from slackbot.bot import default_reply

pythonのデフォルトライブラリからrequests, datetime, reを、
slackbotからlisten_toとdefault_replyを使用。

@listen_to('<@')
def mention_func1(message):
    api = "https://script.google.com/macros/s/[api]/exec?p1={p1}&p2={p2}&p3={p3}&p4={p4}"

if message.body['channel'] == '[channel ID]' :

        bodytext = re.split('\s+|\s*\n\s*', message.body['text'], maxsplit=1)

        userid = bodytext[0].replace('<@', '').replace('>', '')

        if "さんがチャンネルに参加しました" in userid:
            exit()

        p1 = namelist[userid]
        p2 = bodytext[1]
        p3 = namelist[message.body['user']]
        p4 = datetime.date.today()

        url = api.format(p1=p1, p2=p2, p3=p3, p4=p4)
        r = requests.get(url)

        message.reply('褒めを受け付けました!')

最初、特定のカスタム絵文字+@username で反応するようにしようとしたところ、
カスタム絵文字の使い方がわからない社員がいることがわかり、特定のチャンネルでメンションつけたら動くことにしました。

slackbotが受け取るメッセージでは、した人のIDがSlackのユーザーIDになっていたり、メンション部分が<@USERID> となっています。
運用上表示名で保存したかったので、表示名とユーザーIDのobjectを別に作成、ユーザーIDを表示名に変換しています。

最後にrequestsでURLを叩くよう記載して終わり。

アウトプット

slackでメンションつけてメッセージを書き、無事保存されたらbotから返事が来ます。

保存されたデータは1月ごとに集計されて、した/された回数やメッセージをデータポータル上で確認できます。
一旦回数とメッセージだけにしましたが、ユーザー毎に作ったり、別の要素で集計したりと言うのが簡単にできるので、今後の運用でデータポータルも変えていければいいなーと思った次第です。

参考