【GAS】Googleスプレッドシートを更新したらSlackに通知させる仕組みを作ってみた


はじめに

  • スプレッドシートに起票を行った際に、都度手動でSlackに起票の旨を通知していたので、自動化出来ないかなと思い、調べてみました。
  • すると、やりたい事にぴったりの記事を発見。

Googleスプレッドシートに書き込まれたらSlackに通知する
https://toranoana-lab.hatenablog.com/entry/2020/03/13/173949

  • 本記事ではGoogle Apps Script (以降、GAS)を使って更新通知を発行する処理をご紹介します。

前提条件

  • 次のようなレビュー記録表に対して、以下の条件で更新通知を送る。

  ① 内容(D列)に起票があった場合は通知(変更・削除時は通知しない)
  ② 対策・処理(I列)に起票があった場合は通知(削除時は通知しない)
  ③ 確認(O列)に起票があった場合は通知

手順

  1. 準備:Webhook設定
  2. onEditの作成:変更前・変更後のセルの値によって処理を判断
  3. sendSlackの作成:1のWebhook URL宛にAPIを送信
  4. トリガーの作成

1. 準備

Slackへの投稿を行うには、事前にWebhookの設定が必要です。

① 次のURLにアクセスします。
https://my.slack.com/services/new/incoming-webhook/

② [チャンネルへの投稿]欄で、更新通知を送りたいチャンネルを選択し、[Incoming Webhook インテグレーションの追加]をクリック。
※ 今回はテスト用に自身のダイレクトを選択しました。

③ インテグレーションが追加されたチャンネルには、次のようなメッセージが通知される。

④ 先ほどのブラウザに戻ると、Webhook URLが発行されているので、こちらをコピーしておく。(以降の手順で使用します。)

2. onEditの作成

① GASのエディタは、スプレッドシートから[ツール]->[スクリプトエディタ]で開くことができる。

② こちらにonEdit(e)イベントで、変更セルの値を特定する処理を書いていきます。

/////////////////////////////////////////////////
// onEdit(e):slack更新通知                     //
////////////////////////////////////////////////

function onEdit(e) { 
  var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet(); // スプレッドシート(book)
  var activeSheet = activeSpreadsheet.getActiveSheet();          // アクティブシート(sheet)

  if(activeSheet.getName() != "レビュー記録表"){
    // 特定のシート以外の時は処理を中断する
    return;
  }


  var activeCell = activeSheet.getActiveCell();                   // アクティブセル
  var activeValue = activeCell.getValue();                        // アクティブセルの値
  var oldValue = e.oldValue;                                      // 変更前のアクティブセルの値
  var newInputRow = activeCell.getRow();                          // アクティブ行
  var taskNo = activeSheet.getRange(newInputRow, 1).getValues();  // レビューNo 
  var spreadsheetUrl = "https://docs.google.com/spreadsheets/d/xxxxxxx/edit#gid=0&range=A";  // スプレッドシートのURL


  if(activeCell.getColumn() == 4 && activeValue != "" && oldValue == null){
    // ①内容(D列)に起票があった場合は通知(変更・削除時は通知しない)    

    // 送信するSlackのテキスト
    var slackText = "【起票】No." + taskNo + " に課題が起票されました。 \n" + spreadsheetUrl + newInputRow;
    sendSlack(slackText);


  } else if (activeCell.getColumn() == 9 && activeValue != ""){
    // ②対策・処理(I列)に起票があった場合は通知(削除時は通知しない)

    // 送信するSlackのテキスト
    var slackText = "【回答】No." + taskNo + " の課題に回答が追記されました。 \n" + spreadsheetUrl + newInputRow;
    sendSlack(slackText);


  } else if (activeCell.getColumn() == 15){
    // ③確認(O列)に起票があった場合は通知

    if (activeValue == "OK"){
      // 送信するSlackのテキスト
      var slackText = "【確認】No." + taskNo + " の課題がクローズされました。 \n" + spreadsheetUrl + newInputRow;
      sendSlack(slackText);

    } else if (activeValue == "NG") {
      // 送信するSlackのテキスト
      var slackText = "【確認】No." + taskNo + " の課題が却下されました。 \n" + spreadsheetUrl + newInputRow;
      sendSlack(slackText);  

    }


  } else {
    // 条件に該当しない変更の場合は処理を中断
    return;
  }


}
  • 書式はJava Scriptベース。
  • getActiveSpreadsheet()、getActiveSheet()で、現在のスプレッドシートおよびシートを取得できる。
  • getValue()で現在(変更後)のセルの値が取得できる。
  • e.oldValueで変更前のセルの値が取得できる。
  • スプレッドシートURLの末尾に「#gid=0&range=[セルの位置] 」を付与すると、指定のセルの位置にリンク先を指定することができる。(今回は変更セル行のA列にリンクするように設定しました。)
  • 更新箇所によって通知するメッセージを変更。

3. sendSlackの作成

更新通知の判定処理が書けたら、次に通知内容をSlackに送信する処理を書きます。

/////////////////////////////////////////////////
// sendSlack:slackに更新通知を送信            //
////////////////////////////////////////////////

function sendSlack(slackText){
  // slackにて追加したWebhook URLを設定
  var webHookUrl = "https://hooks.slack.com/services/xxx/xxx/xxx";

  var jsonData =
      {
        // "channel": "#general",   // 通知したいチャンネル(自身にダイレクト送信する場合はコメントアウト)
        'icon_url': "https://entershare.jp/wp-content/uploads/2017/11/unnamed.png",
        "text": slackText,
        "link_names": 1,
        "username": "レビュー記録表"
      };

  var payload = JSON.stringify(jsonData);

  var options =
      {
        "method": "post",
        "contentType": "application/json",
        "payload": payload
      };

  // リクエスト
  UrlFetchApp.fetch(webHookUrl, options);
}
  • Slack通知するための情報(チャンネルやアイコン、送信するテキスト)をJSON形式で作成し、JSON.stringify() でSlack送信用のリクエストパラメータを生成する。
  • UrlFetchApp.fetch() を使って、1の手順で取得したWebhook URL宛にAPIのリクエストを送信する。
  • "channel"には、更新通知を送るチャンネル名を入力する。(自身に送信する場合はコメントアウトでOK)

4. トリガーの作成

① GASエディタより、[編集]->[現在のプロジェクトのトリガー]でトリガー作成画面に遷移する。

② 右下の[トリガーの追加]をクリック。

③ イベントソースを「スプレッドシートから」、イベントの種類を「編集時」にし、[保存]をクリック。

結果

起票時にSlackに更新通知が届くようになりました!

上手く実行ないとき

1.GASを実行できない

GASの設定画面にある「Google Apps Script API」がオフになっていないことを確認してください。
(筆者はここで詰まりました)

2.イベントソースに「スプレッドシートから」が表示されない

端末にGoogleアカウントが複数紐づけられている場合に発生する不具合です。
使用するアカウント以外を全て削除し、キャッシュをクリアして再度トリガー設定してください。
(筆者はここでも詰まりました)

参考:
https://teratail.com/questions/256202