実務経験4ヶ月のインターン生がGASを用いて勤務報告を自動化してみた

## 初めに
閲覧していただき、ありがとうございます！
現在からくり株式会社でiOSエンジニアとしてインターンしております。
今回勤務報告を自動化してみたので、そちらを記事にしたいと思います😁

## 背景
インターン生（アルバイト）は月に一回勤務報告をSlackでしないといけないのですが、
いつも手入力で報告しており、これが滅茶苦茶めんどくさい、、、
「月1の作業くらい頑張れよ😡」という野次が飛んできそうですが、
なんせエンジニアなので楽したい性分なのです😢


## そもそもGASとは？？
Google Apps Script(GAS)とは、Googleが提供するサーバーサイド・スクリプト環境のことです。
スプレッドシートやGoogleフォームなどのサービスを、
JavaScriptをベースとしたプログラム言語を使って操作することができます。

## 実装方針
<img width="1138" alt="スクリーンショット 2019-12-22 21.10.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436035/c105598a-956e-170d-c5b8-8ca91c35db76.png">

インターン生は上記写真のように出勤日時をGoogleカレンダーに記入しなくてはいけないので、
これらイベント情報を抽出して出勤時間を計算していきたいと思います。
 
## 1.カレンダーから出勤のイベントを抽出
```JavaScript
const myCalendar = CalendarApp.getCalendarById('自分のカレンダーID');
const attendanceDays = myCalendar.getEvents(getFirstDate(new Date()), getLastDate(new Date()), {search: "出勤"});
```
``` JavaScript
//月の初めを取得
function getFirstDate (date) {
  return new Date(date.getFullYear(), date.getMonth(), 1);
}

//月の最後を取得
function getLastDate (date) {
  return new Date(date.getFullYear(), date.getMonth() + 1, 0);
}
```
`getCalendarById`メソッドを用いて自分のGoogleカレンダーを取得後、
`getEvents`メソッドを用いて出勤のイベントだけを抽出します。


## 2.勤務時間を計算
```JavaScript
for(var i = 0; i < attendanceDays.length; i++) {
   var attendanceTime = attendanceDays[i].getStartTime()
   var leavingTime = attendanceDays[i].getEndTime()
   var actualWorkingHours = getActualWorkingHours(leavingTime.getHours(), attendanceTime.getHours())
}
```
```JavaScript
//実働時間を取得
function getActualWorkingHours(leavingTime, attendanceTime) {
  actualWorkingHours = leavingTime - attendanceTime
  if (actualWorkingHours == 9) {
    return actualWorkingHours - 1
  } else {
    return actualWorkingHours
  }
}

//休憩時間を取得
function getBreakTime(workingHours) {
  if (workingHours == 9) {
    return 1
  } else {
    return 0
  }
}
```
取得してきた各々のイベントの終了時刻`getEndTime()`と開始時刻`getStartTime()`を取得し、
その差分を計算します。
また、フル勤務の際(10:00~19:00)は1時間休憩をとる必要があり、
実働時間を正確に計算する為、差分から1時間引きます。

## 3.Slackに投稿
```JavaScript
function postMessage() {
  
  var url = "https://slack.com/api/chat.postMessage";
  
  var payload = {
    "token" : "アクセストークン",
    "channel" : "投稿したいチャンネルのID",
    "text" : "<@メンションしたい相手のID>投稿するメッセージ,
    "as_user" : true
  };
  
  var params = {
    "method" : "post",
    "payload" : payload
  };
  
  UrlFetchApp.fetch(url, params);
}
```

SlackAPIの`chat.postMessage`に関しては[コチラの記事](https://tanuhack.com/gas-slackapi-postmessage/)がわかりやすいです。

## 4.Google Apps Scriptにトリガーを追加する
最後に月の初めに自動で実行されるようにGoogle Apps Scriptにトリガーを追加します。

プロジェクトのトリガーボタンからトリガーの設定をします。
<img width="322" alt="スクリーンショット 2019-12-23 1.39.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436035/350bde2f-db94-5f9d-40c5-3b75309c800f.png">
トリガーの一覧画面右下のトリガーを追加ボタンを選択します。
<img width="1153" alt="スクリーンショット 2019-12-23 1.39.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436035/b10cb91d-41a3-cea0-c540-f3bed9fcd803.png">

イベントのソースを選択で定期的に実行したい時間を適宜設定します。 
今回は月の初めに実行してほしいので、下記のように設定しました。

<img width="704" alt="スクリーンショット 2019-12-23 11.04.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436035/b86fac6c-0cef-4790-d63a-c824a6fd4b39.png">

これで月の初めに自動で実行されるようになりました！


## 成果物
<img width="422" alt="スクリーンショット 2019-12-22 21.52.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436035/773bc35b-c1d5-91c6-2198-714433c82c0d.png">
これで毎月の勤務報告を手入力をしなくても
自動で勤務報告ができるようになりました！（送り忘れることもなし）

## まとめ
普段Swiftを書いていて、今回初めてJavaScript(GAS)を触ったのですが、
なんとか形にすることができてとりあえずホッとしてます笑（なんせこの土日で勉強して書いた為、、、ギリギリ💦）
まだ交通費の記入や15分単位での計算に対応できてないので、
その辺りを改善していきたいと思います。
また、コードを書いている内にあれも自動化したいな〜🤔
みたいなのが色々出てきたので、社員の方がより重要な業務に時間を割けるように
無駄な作業はインターン生で自動化していければなと思います！
（社員さんは忙しくてなかなか手が回らないので、、、）

## 最後に
僕がインターンをしている[からくり株式会社](https://caraquri.com/)では現在エンジニアを募集しているそうです！
（インターン、新卒、中途問わず）
興味がありましたら、是非一度遊びに来てくださいね〜！！
[Wantedly](https://www.wantedly.com/companies/caraquri)