[GAS] 毎週KPTテンプレート（スプレッドシートのシート）を作成してチャットに通知するスクリプト


# 目的

毎週金曜日にチームは以下のような KPT テンプレートで1週間の振り返りをしている。スプレッドシートを利用しています。
このテンプレートに 1週間内で K:いいと思ったこと、P:わるいと思ったこと、T:トライしたいこと をそれぞれ書き出しを行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63607/4da05c2d-de85-27e4-61d6-656297fe3cac.png)

ですが、1週間の内に起こったことを金曜日に全部思い出すのはむずかしいです。
そのため、GoogleAppsScript (GAS) で週初め時点にはシートを作ってチャットに貼っておくようにしました。これによりKPT項目を随時書き込めるようになりました。

この記事は GAS を設定した方法を紹介します。

# 方法

1. スプレッドシートに `template` という名前のシートを作成する。
1. スプレッドシートの「拡張機能」->「Apps Script」を開き、以下を行う。
  1. コードをコピーする。
  1. トリガーを追加する。
1. postToChat 部分を利用しているチャットツールによって実装する。

## スプレッドシートに `template` という名前のシートを作成する。

コピー元として利用するシート。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63607/f2471f03-5038-79e1-9216-d59f0233ca90.png)

## スプレッドシートの「拡張機能」->「Apps Script」を開く。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63607/db6015da-77e0-beb4-5f20-3eef0c46e994.png)

### コードをコピーする。

コードは以下です。

```js

function main()
{
  const FRIDAY = 5;
  const nextDate = getNextDayDate(FRIDAY);
  const nextDateString = Utilities.formatDate(nextDate, 'Asia/Tokyo', 'yyyyMMdd');
  Logger.log(nextDateString);

  // スクリプトに紐付いたスプレッドシートを読み込む
  let spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  // コピー元のシート
  let templateSheetName = "template";
  let templateSheet = spreadsheet.getSheetByName(templateSheetName);
  // 作成するシート名
  let nextSheetName = nextDateString;
  let nextSheet = getOrCreateSheet(spreadsheet, templateSheet, nextSheetName);

  let sheetUrl = getSheetUrl(spreadsheet, nextSheet);
  Logger.log(sheetUrl);
  const message = Utilities.formatString("今週のKPTシート: %s", sheetUrl);
  postToChat(message);
}

// 次の dayOfWeek (日:0 〜土: 6)曜日の日付を取得する。
function getNextDayDate(dayOfWeek)
{
  let nextDate = new Date();
  let days = dayOfWeek - nextDate.getDay()
  days = days <= 0 ? days + 7 : days;
  nextDate.setDate(nextDate.getDate() + days);
  return nextDate;
}

// 指定されたシート名のシートを作る。
function getOrCreateSheet(spreadsheet, templateSheet, sheetName)
{
  let sheet = spreadsheet.getSheetByName(sheetName);
  if (sheet !== null)
  {
    return sheet;
  }
  // テンプレートシートを同一のスプレッドシートにコピー
  let newSheet = spreadsheet.insertSheet(1, {template: templateSheet});
  newSheet.setName(sheetName);
  return newSheet;
}

// シートへのリンクURLを取得する。
function getSheetUrl(spreadsheet, sheet)
{
  return Utilities.formatString("%s#gid=%s", spreadsheet.getUrl(), sheet.getSheetId());
}

// 任意のチャットツールにメッセージを送信する。
function postToChat(message)
{
  Logger.log(message);
}
```

以下、いくつか説明です。

#### 曜日指定

```js
main 部分
  const FRIDAY = 5;
  const nextDate = getNextDayDate(FRIDAY);
...

// 次の dayOfWeek (日:0 〜土: 6)曜日の日付を取得する。
function getNextDayDate(dayOfWeek)
```

main 部分の FRIDAY は金曜日を表す数値を指定しています。プログラミング上、曜日を数値で表すことがあります。
getNextDayDate のコメントの通り曜日を表す数値は、日曜日は0,月曜日は1,というように進むごとに値が1ずつ増えていき、土曜日は6になります。

#### 作成するシート名を `yyyyMMdd` にしている

同じスプレッドシート内には同じ名前のシートを複数作成できません。

```js
  const FRIDAY = 5;
  const nextDate = getNextDayDate(FRIDAY);
  const nextDateString = Utilities.formatDate(nextDate, 'Asia/Tokyo', 'yyyyMMdd');
  Logger.log(nextDateString);
...
  // 作成するシート名
  let nextSheetName = nextDateString;
```

main 部分の抜粋です。次の金曜日の日付を `yyyyMMdd` 形式の文字列にしており、nextSheetName にその文字列を利用しています。
これにより毎週作成するシート名が変わるため、毎週このスクリプトを実行しても同じ名前のシートができないようになっています。

`Utilities.formatDate` の第2引数でタイムゾーンを指定しています。GAS 自体のタイムゾーンはマニフェストファイルで決めます。合わせることが必要です。参考記事は以下です。

https://masa-enjoy.com/gas-dateobject-timezone

### トリガーを追加する。

トリガーとは、自動で実行する仕組みです。
今回は月曜日のお昼に自動で実行してほしいです。
Apps Script の画面で設定できます。

左の時計アイコンのトリガーを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63607/a3a7e247-b802-9310-c9ae-c4ccfc905271.png)

「トリガーを追加」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63607/05062a35-4e65-5a9f-9363-514867faa470.png)

以下のように指定します。
イベントのソースとは、どんな条件で自動実行するかの指定方法です。
今回の目的だと時間主導型の「週ベースのタイマー」で毎週を指定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63607/5ff5e940-f96b-dae7-9cbe-27dc834bdb2a.png)

時刻は1時間の幅で指定できます。分単位まで指定したい場合、以下の記事を参考します。

https://tonari-it.com/gas-trigger-set/

## postToChat 部分を利用しているチャットツールによって実装する。

引数 message に `今週のKPTシート: [シートへのURL]` を受け取ります。
これをチャットに送ることでワンクリックで作成したシートへ飛ぶことができます。スプレッドシートの場所を覚えておく必要がほぼなくなりかなり便利です。