Google スプレッドシートへの変更を一定の時間間隔で Chatwork に通知する

今回は GAS (Google Apps Script) を用いて、Google スプレッドシートの変更履歴を記録しておき、その件数を一定の時間間隔で Chatwork に通知してみます。なお、変更履歴は Log という名前のシートに保存し、通知が完了するたびにリセットします。

まず、適当なスプレッドシートを準備し、あらかじめ Log シートを作成しておきます。そしてスプレッドシートの [ツール] > [スクリプトエディタ] でスクリプトエディタを開いたら、以下のコードを入力します。API トークンを発行する方法はこちらをご確認ください。ルーム ID は、チャットルームの URL に含まれる、rid より後の数字です(https://www.chatwork.com/#!rid<この部分>)。

var chatwork = {
 apiToken: '<YOUR_API_TOKEN>',
 roomId: '<YOUR_ROOM_ID>'
}

// n 分ごとに実行する
function notifyChatwork() {
 const logSheet = SpreadsheetApp.getActive().getSheetByName('Log');
 
 // Log シートが空ということは、過去 n 分間に編集されていない
 if (logSheet.getDataRange().isBlank()) return;
 
 const client = ChatWorkClient.factory({ token: chatwork.apiToken });
 client.sendMessage({
   room_id: chatwork.roomId,
   body: logSheet.getLastRow() + '回の編集が行われました'
 });
 
 logSheet.clear();
}

// スプレッドシートが編集されるたびに実行する
function insertLog(e) {
 if (e.source.getSheetName() === 'Log') return;
 
 const logSheet = SpreadsheetApp.getActive().getSheetByName('Log');
 
 logSheet.appendRow([
   Moment.moment().format('YYYY-MM-DD HH:mm:ss'),
   e.source.getSheetName(),
   e.user.getEmail(),
   e.range.getRow(),
   e.range.getColumnIndex()
 ]);
}

上記のコードでは、ライブラリを 2 つ導入しています。Chatwork API を利用するための ChatWorkClient と、日時を操作するための Moment.js です。ライブラリの追加は、スクリプトエディタの [リソース] > [ライブラリ] から行います。

画像2

[Add a library] フィールドに入力する、各ライブラリのプロジェクトキーは次のとおりです。

ChatWorkClient:
M6TcEyniCs1xb3sdXFF_FhI-MNonZQ_sT
Moment.js:
MHMchiX6c1bwSqGM1PZiW_PxhMjh3Sh48

最後に、スクリプトエディタの [編集] > [現在のプロジェクトのトリガー] > [トリガーの追加] から、notifyChatwork 関数 が一定の時間間隔で実行されるように、また、スプレッドシートが編集されるたびに insertLog 関数が実行されるように設定します。以下の図は、notifyChatwork 関数のトリガー(左側)と insertLog 関数のトリガー(右側)の設定例です。

イベントのソースを選択

ここで留意しておくべきは、上記の操作を行ったアカウントでしか、トリガーの設定を編集できない(らしい)ということです。プロジェクト内の全ユーザーが編集できる状態にしたければ、画面操作で notifyChatwork 関数と insertLog 関数をトリガーに追加するのではなく、次のように設定をコード化しなければなりません。

function setTriggers() {
 ScriptApp.newTrigger('notifyChatwork')
   .timeBased()
   .everyMinutes(1)
   .create();
 
 ScriptApp.newTrigger('insertLog')
   .forSpreadsheet(SpreadsheetApp.getActive())
   .onEdit()
   .create();
}

この setTriggers 関数を適当な日時にトリガーすれば、その日時以降、先述の条件で notifyChatwork 関数と insertLog 関数が実行されるようになります。

画像4

以上が、スプレッドシートへの変更を一定の時間間隔で Chatwork に通知するための手順です。

画像3

(追記)スプレッドシートに編集履歴を残したいとき

上記の手順では、Log シートに出力した編集履歴を Chatwork への通知のたびにリセットしています。しかし、履歴は残しておきたいというニーズもあるかと思うので、その方法の一つを追記します。

今回は、Log シートに列見出しを用意しておきます。

画像5

これに合わせて、insertLog 関数に変更を加えます。

function insertLog(e) {
 if (e.source.getSheetName() === 'Log') return;
 
 const logSheet = SpreadsheetApp.getActive().getSheetByName('Log');
 
 logSheet.appendRow([
   e.source.getSheetName(),
   e.user.getEmail(),
   Moment.moment().format('YYYY-MM-DD HH:mm:ss'),
   'FALSE'
 ]);
}

insertLog 関数が一度実行されると、結果は次のようになります。

画像6

そして、notifyChatwork 関数は「D 列の 2 行目以降の FALSE を数え上げて Chatwork に通知するとともに、それらの FALSE を TRUE に書き換える」処理に変更します。

function notifyChatwork() {
 const logSheet = SpreadsheetApp.getActive().getSheetByName('Log');
 const logSheetRows = logSheet.getRange(1, 1, logSheet.getLastRow(), logSheet.getLastColumn()).getValues();
 const header = logSheetRows.shift();
 
 var count = 0;
 logSheetRows.forEach(function(cells, index) {
   if (cells[cells.length - 1] === false) {
     count++;
     logSheet.getRange('D' + (index + 2)).setValue('TRUE');
   }
 });
 
// FALSE が 1 つもない場合は通知しない
 if (count === 0) return;
                      
 const client = ChatWorkClient.factory({ token: chatwork.apiToken });
 client.sendMessage({
   room_id: chatwork.roomId,
   body: count + '回の編集が行われました'
 });
}

画像7

以上が、スプレッドシートに編集履歴を残しつつ、Chatwork に通知するための手順です。


この記事が気に入ったらサポートをしてみませんか?