🤖

Slackで打刻するTimeTreeの勤怠管理 #TimeTreeアドカレ

2023/12/08に公開

これは株式会社TimeTree Advent Calendar 2023の8日目の記事です。

https://qiita.com/advent-calendar/2023/timetree

TimeTreeのフロントエンドエンジニアの @fujikky です。

TimeTreeでは、柔軟な働き方を支援するために「出退勤時間の自由(フルフレックス制度)」を導入しています。この制度は、朝型や夜型のメンバーが最適なパフォーマンスを発揮できるだけでなく、子育て中のメンバーが柔軟に働けるなど、プライベートを大切にすることができます。
https://timetreeapp.com/intl/ja/newsroom/2020-05-20/workstyle

私の例だと、最近は週に一度程度しかオフィスに出勤していませんが、コロナ前は毎日午前中は近隣のカフェで仕事をし、午後にオフィスに行くことで通勤ラッシュを回避するなど、快適な仕事環境を享受していました。

しかしながら勤怠管理をまったくやっていないわけではなく、法令順守と健康管理のために、出退勤時間を記録しています。これは単に「働きすぎていないか」を確認するためのものであり、そのためにTimeTreeでは創業時からSlackを用いて勤怠管理を行っています。

Slackでの勤怠管理

Slackの勤怠用チャンネルで「おは」「おはよう」などと発言すると出勤となり、「おつ」「お疲れ様」などと発言すると退勤となります。打刻忘れをした場合でも「おは 10:00」と発言することで、その時間での打刻ができるので、ほとんどのケースをSlack上でカバーできるようになっています。

オフィス勤務の場合は「オフィスおは」と発言するとオフィスでの勤務開始扱いとなります。これによりシステム上でオフィス勤務とリモート勤務の判定ができるようになり、オフィスの混み具合の推移を調べたり、通勤手当の支給などに使っています。

また休みの場合は「本日体調不良のため休みます」などと発言すると休暇扱いとなります(勤怠管理システムへの登録は課題あり)



「おは」「おつ」で打刻

Slackを用いることで以下のメリットがあります。

  • 誰が出社し、退社したかが一目でわかる
  • 病欠などの情報が容易に把握できる
  • コミュニケーションが促進される(お大事にスタンプなど)

GAS時代

初期はGoogle Apps Script(GAS)を用いて、スプレッドシートに勤怠情報を記録していました。
以下のスクリプトをベースにGASのウェブアプリケーションを運用していました。よくできていたので小規模な組織ではまだ充分に使えると思います。
https://github.com/masuidrive/miyamoto

この時期には、打刻時のコメントをランダムに生成したり、docomoさんの雑談対話APIを組み込んで、打刻時に楽しい会話ができるように工夫していました。今だったらChatGPTを組み込むのも良さそうですね。


雑談APIを組み込んだ会話

ちなみにこのBotは社員の一人の提案で「monica」と名付けられました。以降、内部システムが変わってもBotはずっとmonicaの名前を引き継いでいます。

KING OF TIMEへの移行

2019年ごろに社員の増加と労務管理の厳格化に伴い、KING OF TIMEへの移行が決定しました。KING OF TIMEは柔軟性の高い労務管理とAPIの提供が選定の理由となりました。

これに伴い、GASのシステムからTypeScript製の内製アプリケーションに移行しました。内製化されたシステムでは、Slackでの勤怠管理の使いやすさは変わらず、バックエンドをKING OF TIMEに繋げることで信頼性を高めることができ、さらに社内の要望に合わせて機能を追加することができるようになりました。

KING OF TIME の APIは打刻以外のエンドポイントに利用不可時間が設定されており、自由にデータを取得することはできなかったので、一時的なストレージをBotサーバー上に持つ必要がありました。

https://developer.kingtime.jp/

インフラはHerokuで、フレームワークは Slack Bolt を使い、社員情報や今日の打刻情報など一時的なストレージとしてRedisを使っています。

ゴミ捨て当番の抽選

弊社のオフィスはまだ小規模なこともあり、清掃はルンバ、ゴミ捨てはメンバーの持ち回りで行っています。ローテーションにすると、該当のメンバーが当日出社するとは限らないため、抽選でゴミ捨て当番を決めるようにしました。最近当たった人は当たりにくくなるように配慮もされています。ランダムで二人選ばれるため、あまり会話したことのないメンバー同士のコミュニケーションの促進にも繋がります。


「じゃあ◯時に一緒に片付けましょうか」などのコミュニケーションが生まれる

  • ゴミ捨て当番選出ロジック
  • ストレージから過去10回選ばれた人を取得
      - オフィスで働いているメンバーを取得 → リストA
      - 前回で選択されていない人を抽出 → リストB
      - 過去10回選択されていない人を抽出 → リストC
  • リストCからランダムで1人選ぶ、リストCが空だったらBから、それも空だったらAから1人選ぶ
  • 1人目を除いて同じ選出ロジックを走らせる
  • →最近当たった人は当たりにくくなるが、どちらにせよオフィスにいる誰かは当たるようになる
参考コード
async selectCleanerRandomly({
  date,
  excludes,
}: {
  date: string;
  excludes: string[];
}) {
  const [{ officeWorkers }, latestCleaners] = await Promise.all([
    this.getMemberStatuses({ date }),
    this.storage.getLatestClearners(),
  ]);
  // オフィスで働いている人からexcludeを除いたひとが候補者
  const candidates = officeWorkers.filter(
    (nickname) => !excludes.includes(nickname)
  );

  // 過去10回選択されていない人のリスト
  const notSelected = candidates.filter(
    (nickname) => !latestCleaners.includes(nickname)
  );

  // 直近で選択されていない人のリスト
  const notLatestSelected = candidates.filter(
    (nickname) => !latestCleaners.slice(0, 2).includes(nickname)
  );

  // ランダムで一人目を選ぶ
  const member1 = selectRandomly(notSelected, notLatestSelected, candidates);
  if (!member1) return [];

  // ランダムで二人目を選ぶ
  const member2 = selectRandomly(
    notSelected.filter((nickname) => nickname !== member1),
    notLatestSelected.filter((nickname) => nickname !== member1),
    candidates.filter((nickname) => nickname !== member1)
  );
  const members = member2 ? [member1, member2] : [member1];

  // 過去選択された人リストに追加
  await this.storage.appendClearners(members);

  return members;
}

勤怠ステータスの表示

打刻時にリモート勤務かオフィス勤務かの情報が得られているので、それに基づいて各メンバーの勤務状況を表示するステータスチャンネルを作成しました。打刻などイベント発生時には、Slackの当日の投稿をBotが編集し、常に最新の情報を表示しています。
また、社内配布したChrome拡張を使って、Google Meet や Zoom のリンクを開いているかどうかを検知し、会議中かどうかも表示できるようになっています。


出勤している人、オフィスにいる人、会議中の人などが一目で分かるステータス

交通費申請の自動化

弊社では現在、オフィス勤務をした日だけ交通費が支給されるというルールになっており、毎月何日オフィス勤務したかを本人に申告してもらうことになっていました。毎月のオフィス勤務日数を各々で計算するのは面倒で間違いも起こりやすく、労務メンバーも Slack の打刻履歴を確認するなどの負担がかかっていました。また、リモートワーク、オフィス勤務の打刻データは KING OF TIME の打刻所属というフィールドにも記録されるように作っていました。
そこで、それらの情報を使って、オフィス勤務した日を自動で計算し、人事にそのデータを提供することで、交通費申請の手間や労務業務の負担を減らすことができました。各メンバーには毎月確認のために、DMでオフィス勤務日数が送られてきて、間違いがなければそのままでOKです。変更点があればKING OF TIMEのタイムカード画面で打刻所属を修正してもらう流れになっています。

今後やりたいこと

  • 休暇申請の自動化
    私用や体調不良などで休みを取る場合に「おやすみ」と投稿するとステータス状は休暇になるのですが、KING OF TIMEで休暇申請のAPIが用意されていないため、休暇申請を出すところまではできていません。

  • 打刻修正の自動化
    打刻を間違えてしまうこともあるのですが、修正するには現在はKING OF TIME上で行ってもらっています。これも打刻訂正を申請するAPIが用意されていないためです。

もしこの記事を読んだKING OF TIMEの方がいらっしゃいましたら、ぜひ申請系のAPIの拡充をよろしくお願いします(笑)

まとめ

Slackで勤怠管理をすることで、勤務状況の可視化、コミュニケーションの活性化、労務の負担も減らすことができています。引き続き改善を継続していきたいと思っています。

TimeTreeの採用情報

TimeTreeのミッションに向かって一緒に挑戦してくれる仲間を探しています。TimeTreeで働くことに興味がある方はぜひ、Company Deck(会社紹介資料)や採用ページをご覧ください!

TimeTree Tech Blog

Discussion