GASで日報共有する仕組みを作った話

[Increments × cyma (Ateam Inc.) Advent Calendar 2020](https://qiita.com/advent-calendar/2020/increments-cyma) 11日目は、[Increments](https://increments.co.jp/) 株式会社 Qiita Jobs カスタマーGの中泉（[@zumi0](https://qiita.com/zumi0) ）が担当します！

マーケティング担当ではありますが、このアドベントカレンダーに参加させていただけてとても嬉しいです！


## はじめに
私は、今年の4月に株式会社エイチームに入社した新卒のマーケターです。入社してから約4週間の新卒研修の後、Incrementsに配属されました。

新卒研修の間は同期内で日報共有がされていて、私はそれを読むのが好きでした。しかし、事業部に配属されると、事業部内のメンバーの日報しか読むことができなくなってしまいました… 同期の日報が読みたかった私は、弊社社員全員がGoogle Workspace（旧G Suite）を使えることから、Google FormとGmailで日報共有ができると思い、GASを使って日報共有する仕組みを作りました。


## 日報共有
### 日報が共有されるまでの流れ
前述したとおり、私が作った日報共有の仕組みでは、Google FormとGmailを使います。日報が共有されるまでの流れを簡単にまとめたのが以下です。

1. 日報をGoogle Formで回答する
2. 1日分の日報が集まったシートを作成する
3. 作成されたシートからメール文面を作成する
4. 文面を使ってメールを送信する
5. 2~4をGASの定期実行機能を使って動かす

### 1. 日報をGoogle Formで回答する
日報共有する際に以下のようなGoolge Formを用意した。
回答項目は、名前や所属だったり、いつの日の日報かなどです。

![dailyreport.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618736/2c5df774-5d7e-c41f-c5b3-3fb620d89f14.png)


### 2. 1日分の日報が集まったシートを作成する
Google Formの回答は、自動でスプレッドシートに記入されます。毎日回答が同じシートに溜まっていくと、メールの文章が作成しにくかったり、管理が大変だと思ったので、1日ごとにシートを作るようにしました。

シートの作成は、スプレッドシートを指定してあげれば簡単にできます。シート名は、日付にしてあります。

```js
// 日付の取得
// 次の日の朝に日報を送信しているため、substract関数で1日前の日付を取得している
var today = Moment.moment().subtract(1, 'days').format('YYYY/MM/DD');

// スプレッドシートの指定
var spreadsheet = SpreadsheetApp.openById('シートのID');

// シートの作成
var todaySheet = spreadsheet.getSheetByName(today);
if (!todaySheet) {
  todaySheet = spreadsheet.insertSheet(today);
} else {
  todaySheet.clearContents();
}
```

作成したシートに、1日分の日報をコピーする関数は以下です。
全ての回答が記録されているシートから、指定した日程と同じ日の日報のみをコピーしています。

```js
function copyReport(mainSheet, today, todaySheet) {
  // 全ての回答が記載されているシートで、データが記載されている範囲のデータを取得
  // 全ての回答を取得しないように、予め大体の人数を決めてmaxPersonで指定しておく
  var maxPerson = 20;
  var lastRow = mainSheet.getLastRow();
  var data = mainSheet.getRange(lastRow-maxPerson, 1, lastRow-1, 7).getValues();
  
  // 指定した日の日報をコピーする
  for (var array of data) {
    if (today == Moment.moment(array[3]).format('YYYY/MM/DD')) {
      todaySheet.appendRow(array);
    }
  }
}
```

### 3. 作成されたシートからメール文面を作成する
次に、2で作ったシートを読み込み、メール文面を作成します。文面を作成する関数は、以下です。

```js
function makeText(today, todaySheet) {
    // ベースとなるテキスト
    var baseText = today + "の日報です。\n" + 
                   "\n" +
                   "----------------------------------------------\n" +
                   "\n";
    
    // シートから日報のデータを読み取る
    var reportData = todaySheet.getDataRange().getValues();
    // 個人の回答を整形し文面を作成する
    for (var report of reportData) {
      var reportText = "【所属 / 名前】\n" +
                       // report[1] -> 名前
                       // report[2] -> 所属
                       report[2] + " / " + report[1] + "\n" +
                       "\n" +
                       "【本日の日報】\n" +
                       // report[4] -> 日報の内容
                       report[4] + "\n" +
                       "\n" +
                       "----------------------------------------------\n" +
                       "\n";
       baseText = baseText + reportText;
    }

    var text = baseText + 
               "本日の日報は以上です。"
    
    return text;
}

```

### 4. 文面を使ってメールを送信する
次に、3で作成した文面を使ったメールを以下の関数を実行することで送信します。
送信するメールアドレスとリストは1つのシートで管理していて、最初にそのシートを読み込んでリストを作成しています。

```js
function sendGmail(mailSheet, text, today) {
    // 件名の作成
    var subject = today + "の日報";
    
    // メールを送るメンバーのメールアドレスはシートで管理しているので、それを読み取る
    var mailLastRow = mailSheet.getLastRow();
    var addressData = mailSheet.getRange(2, 2, mailLastRow-1, 1).getValues();

    // メールアドレスの配列を作成する
    var addressArray = [];
  
    for (var address of addressData) {
      addressArray.push(address[0]);
    }
    
    // 送信するメールアドレス、件名、本文を指定して、メールを送信する
    GmailApp.sendEmail(addressArray,
                       subject,
                       text);
    
}
```

### 5. 2~4をGASの定期実行機能を使って動かす
最後に、GASの定期実行機能を使い2~4の関数たちを実行させることで、日報共有を実現させています。詳しい定期実行のやり方は、ここでは割愛します。気になる方は調べてみてください。

この定期実行ですが、毎日実行させています。ただそうすると休日や祝日にもメールが送信されてしまうので、以下の休日や祝日を判定する関数を作成し、営業日のみメールが送信されるようにしています。

```js
function isHoliday (today) {
  var datedToday = new Date(today);

  // 土曜日・日曜日だとfalseを返す
  // getDay()での返り値が0だと日曜日、6だと土曜日
  if (datedToday.getDay() == 0 || datedToday.getDay() == 6) {
    return false;
  }
  
  // 祝日だとfalseを返す
  // 日本の祝日というカレンダーがGoogle Calendarにあるので、それで祝日かどうか判定できる
  const calendarId = 'ja.japanese#holiday@group.v.calendar.google.com';
  var calendar = CalendarApp.getCalendarById(calendarId);
  var todayEvents = calendar.getEventsForDay(datedToday);
  if (todayEvents.length != 0) {
    return false;
  } 
  
  return true;
}
```

## おわりに
今回はGASを使った日報共有の方法を紹介させていただきました。今回は日報共有という使い方でしたが、他のことに応用がきくと思います。

[Increments × cyma (Ateam Inc.) Advent Calendar 2020](https://qiita.com/advent-calendar/2020/increments-cyma) 12日目は、株式会社エイチーム EC事業本部の [@river_grl55](https://qiita.com/river_grl55)がお送りします！