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


この記事はGoogle Apps Scriptを実例交えて基礎からざっくり学ぶ Advent Calendar 2017 21日目の記事です。

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

はじめに

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

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

スプレッドシートの準備

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

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

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

GASの準備

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

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++) { // 1行目は説明行なので
    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#[email protected]";
  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);
}

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

  var calendarId = "ja.japanese#[email protected]";
  var holidays = CalendarApp.getCalendarById(calendarId).getEventsForDay(today);

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

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

Chatworkトークンの取得方法は16日目の記事を参照してください。

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

定期実行の設定

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

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

スプレッドシートの調整

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

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

設定例

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

おわりに

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

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

明日

【Google Apps Script】その22 Google Analyticsのデータを引っ張ってくる
となります。
Googleサービス連携の容易さを活かし、GAのデータを持ってきましょう。

前の記事
【Google Apps Script】その20 今日の予定をChatworkに一括通知する
次の記事
【Google Apps Script】その22 Google Analyticsのデータを引っ張ってくる