LoginSignup
20
7

Googleカレンダーへの作業時間登録をアドオンで簡単にした

Last updated at Posted at 2023-12-18

本記事はリンクアンドモチベーション Advent Calendar 2023の19日目になります。

はじめに

弊社では、PJTごとの稼働時間を集計するために活動時間をGoogleカレンダーに記録しています。
これがまあめんどくさい大変なのです。

大変ポイント

  • 入力フォーマットを間違えると正しく集計されない
  • PJTコードを間違えると正しく集計されない
  • 作業 | mtg | 作業 のような時に2つに分けて作業を入力しないといけない

これがあまりにもめんどくさい大変だったので、なるべく楽に・正確に登録できるようにするためにGoogleカレンダーへ作業時間を登録するアドオンを作りました。

Google Workspace Add-onsにしたのは

  • Googleカレンダーで開けるから
  • 同じことで困っている人に配布しやすい
  • 作ってみたかったから

です。

どんなアドオン?

こういう画面がGoogleカレンダーの右に表示されます。

image.png

image.png

入力フォームに各種情報を入力し、「登録を実行」することで開始時刻〜終了時刻まですでに入っている予定は避けて作業時間を登録してくれます。

どうやって作るの?

ざっくりこんな感じです。

  • GASで実装
    image.png
    • UIはビルダーでコード生成してコピペするだけ
  • Google Workspace Marketplaceに内部アプリとして公開

実装や公開方法の詳細に関しては弊社のテックブログでエンジニアが記載した記事があるのでそちらをご参照ください。
私はこの記事を見ながら作りました。

ここからは、今回作る際に工夫したポイントをご紹介します。

工夫ポイント1:大体入力する情報が同じものはUserPropertiesに保存しておく

以下のように、指定のキーで永続化することができます。
ユーザーごとに保存されるので、別のブラウザでログインした場合なども引き継がれます。

const USER_PROPERTY_PJTCODE = 'pjtCode';
const USER_PROPERTY_DESCRIPTION = 'description';
const USER_PROPERTY_OVERRIDE = 'override';

function loadUserProperty(key) {
  const prop = PropertiesService.getUserProperties();
  return prop.getProperty(key);
}

function saveUserProperty(key, value) {
  const prop = PropertiesService.getUserProperties();
  prop.setProperty(key, value);
}

工夫ポイント2:自分が主催者の予定のステータス判定はゲストステータスを見る

主催者だった場合、getMyStatus()ではOWNERと返却されてしまいます。
そのため、ゲストステータスを見るようにしました。
(もっとスマートな方法あれば知りたい)

  // 勤務時間のうち、予定が入っている時間帯を取得
  // 終日の予定、除外する予定は省いて返す
  return events.filter(event => {
    // 終日予定は除く
    if (event.isAllDayEvent()) {
      return false;
    }
    // 上書き対象の予定(ex) NO MTG DAY)は除く
    if (overrideTitles.includes(event.getTitle())) {
      return false;
    }

    // 参加していない予定は除く
    let myStatus = event.getMyStatus();
    if (myStatus === CalendarApp.GuestStatus.OWNER) {
      // 主催者だった場合は、ゲストステータスを見ないと判別できない
      const email = Session.getActiveUser().getEmail();
      const guest = event.getGuestList(true).filter(
        guest => guest.getEmail() === email
      );
      if (guest.length === 0) {
        // 自分だけの予定は作業時間とみなすので参加判定
        myStatus = CalendarApp.GuestStatus.YES;
      } else {
        myStatus = guest[0].getGuestStatus();
      }
    }

    return !excludeStatus.includes(myStatus);
  });

おわりに

社内でも喜んでもらえたので、作って良かったです。
今後も、身近なめんどくさいを撲滅していく際に使ったことがない技術を採用して楽しんでいこうと思います。

20
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
7