Yappli Tech Blog

株式会社ヤプリの開発メンバーによるブログです。最新の技術情報からチーム・働き方に関するテーマまで、日々の熱い想いを持って発信していきます。

交通費申請を楽にするためにSlackのスラッシュコマンドをZapierで作成した

インテグレーション・エンジニアおうえです。 今回は「交通費申請を楽にするためにSlackのスラッシュコマンドをZapierで作成した」という内容を紹介します。

はじめに

ヤプリは社員各自が在宅とリモートを判断することができる「オープン勤務」という勤務体制になっています。
業務状況に応じて在宅とリモートを選択できてとても働きやすいのですが、出社日数が不定なために月末の交通費申請が面倒という問題がありました。

解決案

ヤプリでは勤怠をTeamSpiritで管理しているために、Slack のコマンドを使って TeamSpirit に打刻するの記事にあるngs/ts-dakokuをforkした/tsというSlackのスラッシュコマンドを利用しています。 github.com

/ts を利用した場合、リモート or 出社のいずれかが、Slackチャンネルに定型文で投稿されます。

つまり、Slackに投稿された定型文をカウントすることで、出社回数がカウントできそうな気がしました。

スラッシュコマンドを作るまでの流れ

Zapierの設定 その1

最初にZapierで新しいZapを作成し、1個目のActionとしてWebhooks by Zapierを設定。
EventにはCatch Hookを選択します。
Webhook URLが発行されたら、Zapierの設定は一旦完了です。

Slack側の設定

1. Slack側で新しいアプリを作成

Slackにログインした状態で、Slack API: Applications | Slack にアクセスして、Create New Appをクリックします。
※ 作成できなかった場合は、ログインしているSlackワークスペースの管理者に権限を確認してもらってください。

2. アプリのDisplay Nameを設定

アプリが作成できたら、アプリ設定画面のサイドメニューのFeatures > App Home でDisplay Name (Bot Name)Default Nameを設定します。
これが設定されていないと、ワークスペースにアプリをインストールすることができません。

3. アプリの表示情報を設定

次に、アプリ設定画面のサイドメニューのFeatures > Basic Information でDisplay Informationを設定します。

4. アプリに必要な権限を設定

今度は、アプリ設定画面のサイドメニューのFeatures > OAuth & Permissions > Scopes で アプリに必要な権限を設定します。
今回のアプリだと必要なのは、search:readだけです。

5. 作成したアプリをワークスペースにインストール

また、アプリ設定画面のサイドメニューのFeatures > Basic Information に戻り、Install your appでアプリをワークスペースにインストールします。 インストールした後表示される、OAuth TokenはZapier側で利用します。
※ 今回のアプリでは、search:readを叩くためにUser OAuth Tokenを利用していますが、アプリに必要な権限によってはBot User OAuth Tokenを利用してください。
※ ここでインストールできなかった場合は、ログインしているSlackワークスペースの管理者に権限を確認してもらってください。

6. スラッシュコマンドを作成

最後に、アプリ設定画面のサイドメニューのFeatures > Basic Information > Add features and functionality > Slash Commands から 新しいスラッシュコマンドを作成します。
Create New Command してから必要な情報を入力してください。 Request URLには、先程Zapierで発行されたURLを設定します。

7. スラッシュコマンドを実行してみる

ここまでできたら、一度Slackで実際にスラッシュコマンドを実行してみてください。
Zapierの設定をするためには、一度スラッシュコマンドを実行しておくとやりやすいです。

上のようなメッセージが表示されたら、Slack側の設定は完了です。

Zapierの設定 その2

出勤回数をカウントする

今回は、Code by ZapierのRun Pythonに以下のコードを書いて出勤回数をカウントしました。

import datetime
import requests
import urllib.parse

def search_messages(date, page):
    on = "on:" + last_month()
    if "Text" in input_data and type(input_data["Text"]) == str and input_data["Text"].endswith('月'):
        on = "on:" + input_data["Text"]

    slack_id = "from:<@" + input_data["SlackID"] + ">"
    search = "勤しました"
    query = urllib.parse.quote(search + " " + slack_id + " " + on)
    url = "https://slack.com/api/search.messages?count=100&sort=timestamp&sort_dir=asc&pretty=1&query=" + query + "&page=" + str(page)
    # ↓にはSlackで発行されたOAuth Tokenを設定してください
    header = {"Authorization": "Bearer {}".format("xoxp-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")}

    res = requests.get(url, headers=header).json()
    if res["messages"]["total"] == 0:
        return "先月の出勤回数は0回かも"

    body = ""
    for match in res["messages"]["matches"]:
        dt = datetime.datetime.fromtimestamp(int(float(match["ts"])))
        dt = to_jst(dt)

        current = dt.strftime("%Y/%m/%d")
        if date != current:
            date = current
            body += "\n" + date + " "
        else :
            body += " / "

        body += "<" + match["permalink"] + "|" + match["text"].replace('<', '').replace('>', '').replace('\n', '') + ">"

    if res["messages"]["pagination"]["page"] != res["messages"]["pagination"]["page_count"]:
        body += search_messages(date, res["messages"]["pagination"]["page"] + 1)

    return body

def last_month():
    now = datetime.datetime.now()
    dt = datetime.datetime(now.year, now.month, 1)
    dt = dt + datetime.timedelta(days=-1)
    dt = to_jst(dt)

    return dt.strftime("%m月")

def to_jst(dt_utc):
    return dt_utc.astimezone(datetime.timezone(datetime.timedelta(hours=+9)))

output = [{"body": search_messages("", 1)}]

上のコードでは、/出勤回数集計と入力した場合は前月のデータ、/出勤回数集計 12月のように入力した場合は12月の出勤回数をカウントするようになっています。

カウントした結果をSlackに投稿する

スラッシュコマンドの場合はResponse Urlを使って投稿することで、あなただけに表示されています というメッセージとして投稿できます。
設定は簡単で、3個目のActionとしてWebhooks by Zapierを設定し、URLに1個目のActionの結果にあるResponse Urlを選択します。その他の設定は以下のスクショを参照してください。

実行結果

↑の設定がすべて完了したら、Slackで/出勤回数集計と入力すれば、↓のような集計結果が表示されると思います。
後は表示された結果を見ながら交通費申請をすればHappyになりますー

まとめ

という感じで、ZapierだけでSlackのスラッシュコマンドが簡単に作成できました。
ZapierはPythonやJavaScriptのコードが書けるので、他にも色々なスラッシュコマンドをサーバ等の実行環境を用意せずに簡単に実装できそうです。

ちなみに勝手に作成した上に年末にリリース逃げという無責任コンボを決めましたが、ヤプリのみんなからはいつもどおりのGoodな反応もらえたのが最高のWinですー

最後に

ヤプリではこのようにプロダクトだけでなく業務に関する改善も積極的に行っております。
YappdateDay」などの時間を使って、自動化や効率化に取り組んでいるので、自動化や効率化などに興味がある方がいらっしゃいましたら、ぜひカジュアルにお話しましょう!

open.talentio.com