Slack通知

img

全貌

// ==============================================
// GoogleFormの応答が送信されたときに実行される
// ==============================================
function onFormSubmit(e) {
  // 取得したフォームの回答を変数に代入する
  const formResponse = e.namedValues;
  const itemResponses = formResponse.getItemResponses();

  // 通知メッセージを初期化
  var message = "New response in Google Form:\n";

  // 各質問と回答をメッセージに追加する
  for (var i = 0; i < itemResponses.length; i++) {
    var itemResponse = itemResponses[i];
    message += itemResponse.getItem().getTitle() + ": " + itemResponse.getResponse() + "\n";
  }

  // Slackに通知
  sendNotificationToSlack(message);
}

// ==============================================
// Slackに通知を送る
// ==============================================
function sendNotificationToSlack(text) {
  // Slack の Webhook URL
  const webhookUrl = 'https://hooks.slack.com/services/XXXXXX/XXXXXX/XXXXXX';

  // POST メッセージの設定
  const payload = {
    "text": text
  };

  // HTTPオプションを設定します。
  const options = {
    "method": "post",
    "payload": JSON.stringify(payload)
  };

  // HTTPリクエストを送信
  UrlFetchApp.fetch(webhookUrl, options);
}

トリガー

img

コード解説

関数の発火タイミングを指定する

まず、GoogleFormに回答が来た時にGASが反応して欲しいと思ったので、トリガーを確認しました。
トリガーには “イベントの種類を選択” という選択肢があり、そこには “フォーム送信時” という選択肢があったのでこれを選びます。
(そもそも、onFormSubmit()が予約関数で、これが存在すれば勝手にフォーム送信時に発火してくれるということでしたがいまいちわからんの顔になったので上記設定を行いました。)

フォームに入力された値を取得

フォームが送信された時に発火する関数(ここでは onFormSubmit())は、引数にイベントオブジェクトを持ちます。(ここでは e
e には送信されたフォームの情報が含まれており、具体的には以下のプロパティを持っています。(Googleスプレッドシートのイベント>フォームの送信 を参照)

項目説明
authModeスクリプトの認証モードを表す列挙値
namedValuesフォームのレスポンスの値を連想配列として表す
rangeレスポンスが挿入されたスプレッドシートのレンジオブジェクト
triggerUidトリガーの一意の ID を表す
valuesフォームのレスポンスの値を配列として表す

ファイルへのリンクやユーザー情報を取得できます。

送信されたフォームの内容はnamedValuesで取得できます。

const formResponse = e.namedValues; // 連想配列(key:value)で取得
const itemResponses = formResponse.getItemResponses(); // value(回答内容)を取得

取得した値を、取得した順にmessageとしてstringに突っ込んでいきます。

for (var i = 0; i < itemResponses.length; i++) {
  var itemResponse = itemResponses[i];
  message += itemResponse.getItem().getTitle() + ": " + itemResponse.getResponse() + "\n";
}

namedValuesで取得したformResponseは、スプレッドシートに出力されるのと同じ順序で取得できます。 ですので、回答サンプルを作った時に順序を入れ替えたり加工したりする必要がなければ上記コードで十分です。

Slackに通知を送る

Slackに通知を送るにはWebhookURLが必要です。 取得方法は公式ページに載っているのでここでは割愛します。(数分の作業で取得できます。)

あとはメッセージとオプションを設定してUrlFetchするだけです。
オプションについては公式ドキュメントを見るのが早いです。(Class UrlFetchApp>fetch(url,params)

まれにSlackへの通知時に落ちるので、リトライ処理を入れておくと良いかもしれません。
私はそこまで厳密に管理する気がないので入れませんでした。

function getFormDataWithRetry() {
  var MAX_RETRIES = 3;
  for (var i = 0; i < MAX_RETRIES; i++) {
    try {
      // slackへの送信処理...
    } catch (e) {
      if (i === MAX_RETRIES - 1) {
        Logger.log(`リトライしましたが${MAX_RETRIES}回以上失敗したため、処理を終了しました`);
        Logger.log(error.message)
        throw error;
      }
      // リトライ前に待ち時間を設けます
      Utilities.sleep(Math.pow(2, i) * 60000);
    }
  }
}