【Google Apps Script】その21　指定時刻にメッセージを自動投稿するChatwork botを作る

この記事は[Google Apps Scriptを実例交えて基礎からざっくり学ぶ Advent Calendar 2017](https://qiita.com/advent-calendar/2017/gas_beginner)　21日目の記事です。

本アドベントカレンダーは@rt_pの個人プロジェクトですが、筆者は[Ateam Brides Inc. Advent Calendar 2017](https://qiita.com/advent-calendar/2017/a-t-brides)にも参加しています。そちらでも出張版記事を書いているので、覗いていただけると嬉しいです。

# はじめに

毎日10時にメッセージを送りたい。
毎月1日の12時にメッセージを送りたい。
等、スケジュールに沿ったメッセージをChatworkに送りたいことって多いですよね。

今日はCronのように、メッセージ自動投稿するシステムを紹介します。

![sheet.png](https://qiita-image-store.s3.amazonaws.com/0/199678/a7168606-d586-606c-879d-122b8e14ff7a.png)

![chatwork.png](https://qiita-image-store.s3.amazonaws.com/0/199678/424b9fe9-f181-6bf3-1a97-bad1d49aee76.png)

# スプレッドシートの準備

スプレッドシートを新規作成します。
**そしてシート名（スプレッドシート名ではない）を*タイマー*に変更してください。**
その後、A1セルにカーソルを合わせて以下内容をコピペします。

|分|時|日|月|曜日|土日休|メッセージ内容|部屋|
|---|---|---|---|---|---|---|---|
|*|*|*|*|*|0|テスト|[chatwork部屋ID]|

[chatwork部屋ID]には、自動投稿したい部屋のIDを入力してください。
**※その部屋にChatworkトークンを取得済みのアカウントが招待されている必要があります**

![sheet.png](https://qiita-image-store.s3.amazonaws.com/0/199678/a7168606-d586-606c-879d-122b8e14ff7a.png)

# GASの準備

スクリプトエディタを開き、以下コードに置き換えて実行します。
スクリプトエディタの開き方や*承認が必要です*メッセージが出た際の対処法が分からない場合は
[アドベントカレンダー1日目のHello, world!記事](https://qiita.com/rf_p/items/0535ec495df8f9d2b894)をご参照ください。

```javascript:message_bot.gs
var token = 'YOUR_TOKEN'; // ここにトークンを入力
var ALL = '*';
var COLUMNS = ['minute', 'hour', 'day', 'month', 'week'];

function myFunction() {
  var sheet  = SpreadsheetApp.getActive().getSheetByName('タイマー');
  var values = sheet.getDataRange().getValues(); // 全メッセージリストを取得
  
  var currentTime = new Date();
  var holidayFlg = isHoliday(currentTime);
  
  var times  = {
    'minute':      Utilities.formatDate(currentTime, 'Asia/Tokyo', 'm'),
    'hour':        Utilities.formatDate(currentTime, 'Asia/Tokyo', 'H'),
    'day':         Utilities.formatDate(currentTime, 'Asia/Tokyo', 'd'),
    'month':       Utilities.formatDate(currentTime, 'Asia/Tokyo', 'M'),
    'week':        Utilities.formatDate(currentTime, 'Asia/Tokyo', 'u'),
    'holiday_flg': holidayFlg
  };
  
  for (var i = 1; i < values.length; i++) { // １行目は説明行なので
    executeIfNeeded(values[i], times);
  }
}

// 実行すべきタイミングか判定し、必要であれば実行
function executeIfNeeded(value, times) {
  for (var i in COLUMNS) { // minute, hour, day, month, weekを順番にチェックして全て条件にマッチするか判定
    var timeType = COLUMNS[i];
    if (!isMatch(value[i], times[timeType])) {
      return false;
    }
  }
  
  // 土日休フラグの検証
  if (value[5] == 0 && times['holiday_flg']) {
    return false;
  }
  
  postToChatworkMessage(value[6], value[7]);
}

// 中身が*もしくは指定した数字と一致するか
function isMatch(time, currentTime) {
  return (time === ALL || time == currentTime);
}

// 祝日か判定
function isHoliday(today) {
  var week = Utilities.formatDate(today, 'Asia/Tokyo', 'u');
  if (week == 6 || week == 7) { // 土日判定
    return true;
  }

  var calendarId = "ja.japanese#holiday@group.v.calendar.google.com";
  var holidays = CalendarApp.getCalendarById(calendarId).getEventsForDay(today); // 休日の場合、日本の祝日カレンダーにイベントが登録されている
  return holidays.length > 0;
}

// chatworkにメッセージ投稿
function postToChatworkMessage(body, roomId) {
  var payload = {
    'body': body
  }
  var headers = {
    'X-ChatWorkToken': token
  }
  var options = {
    'method' : 'POST',
    'payload' : payload,
    'headers' : headers
  }
  var url = 'https://api.chatwork.com/v2/rooms/' + roomId + '/messages';
  UrlFetchApp.fetch(url, options);
}
```

あまり変わったことはしていないですが、特筆するならここでしょうか。

```javascript
  var calendarId = "ja.japanese#holiday@group.v.calendar.google.com";
  var holidays = CalendarApp.getCalendarById(calendarId).getEventsForDay(today);
```

Googleカレンダーの「日本の祝日」を取得し、もし今日イベントが登録されていたら休日と判定しtrueを返します。


```javascript
  var token = 'YOUR_TOKEN'; // ここにトークンを入力
```

Chatworkトークンの取得方法は[16日目の記事](https://qiita.com/rf_p/items/3e20e4114a1182deb7bc)を参照してください。

`myFunction()`を実行するとChatworkにメッセージが届けば成功です。

# 定期実行の設定

スクリプトエディタのストップウォッチアイコンをクリックし、以下の通り設定します。

![timer.png](https://qiita-image-store.s3.amazonaws.com/0/199678/e15f0523-d87a-6794-6164-f68045d49509.png)

すると毎分、以下のようにメッセージが届きます。

![chatwork.png](https://qiita-image-store.s3.amazonaws.com/0/199678/424b9fe9-f181-6bf3-1a97-bad1d49aee76.png)

# スプレッドシートの調整

これで毎分「テスト」が投稿されるのを確認できたら、あとはお好きなように設定してください。
Cronのようにカンマ区切りやレンジ指定はできませんが（24日目の記事で触れる予定です）、*（アスタリスク）で無条件配信、数字入力で指定タイミングに配信します。

また、土日休列はCronにない独自実装です。
業務で使っていると土日休日は通知したくないことが多いので、通知しない場合は0を、土日休日も問わず通知したい場合は1を設定してください。

## 設定例

毎日10時0分、平日のみ投稿したい場合は、
分の列に0　時の列に10　あとは*（アスタリスク）を入力、土日休は0を設定します。

# おわりに

今日はGASだけでメッセージ自動投稿botを作成しました。

スプレッドシートで管理しているので、メッセージの登録・編集・削除が非常に容易にでき、非エンジニアにも触ってもらいやすいシステムになっています。
（反面、意図しない変更や入力に注意）

# 明日

[【Google Apps Script】その22　Google Analyticsのデータを引っ張ってくる](https://qiita.com/rf_p/items/a40468f6414703d63df3)
となります。
Googleサービス連携の容易さを活かし、GAのデータを持ってきましょう。

前の記事
[【Google Apps Script】その20　今日の予定をChatworkに一括通知する](https://qiita.com/rf_p/items/3b1874f9a71f0d39ccab)
次の記事
[【Google Apps Script】その22　Google Analyticsのデータを引っ張ってくる](https://qiita.com/rf_p/items/a40468f6414703d63df3)