7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Google Apps ScriptAdvent Calendar 2022

Day 18

GoogleフォームからApps Scriptを呼び出す方法は2つある

Last updated at Posted at 2022-12-18

Googleフォームって便利ですよね。「何をどう回答すればよいか」が一目で分かるので、回答する人が迷わず入力できます。

ただ、フォームに回答があったことの通知はとてもお粗末です。フォームの設定からメールで通知できるのですが、メール本文には「回答がありました」という一言と回答結果へのリンクが掲載されているだけ。どんな回答があったのかを知るためには、リンクをわざわざクリックしなければなりません。

そこでよくやるのが、Apps Scriptを使った通知のカスタマイズです。フォーム送信イベントをトリガーにしてApps Scriptを起動し、通知内容をいい感じに整えたり、通知先をSlackやGoogle Chatに変更します。

このフォーム送信イベントですが、回答を保存する場所に応じて、Googleフォームのイベントと、Googleスプレッドシートのイベントの2種類があります。この記事では、それぞれのイベントについて解説します。また、Apps Scriptのテストを楽にする方法も追記します。

回答を保存する場所に応じて2種類あるフォーム送信イベント

Googleフォームへの回答は、もちろん、Googleフォームに保存されます。さらに、Googleスプレッドシートを紐づけて、そちらにも保存することもできます。スプレッドシートへの紐づけは、フォームの回答タブの右上にあるスプレッドシートアイコンをクリックすると実行できます。

Screenshot 2022-12-18 08.00.21.png

回答を保存する場所に応じて、フォーム送信イベントがそれぞれ準備されています。イベントを処理するApps Scriptも、それぞれフォームもしくはスプレッドシートのスクリプトエディターで記述します。

回答をGoogleフォームに保存 回答をGoogleスプレッドシートに保存
フォーム送信イベント https://developers.google.com/apps-script/guides/triggers/events#form-submit_1 https://developers.google.com/apps-script/guides/triggers/events#form-submit
イベントオブジェクトの属性 authMode, response, source, triggerUid authMode, namedValues, range, triggerUid, values
回答へのアクセス方法 FormResponseクラスのresponse属性。このコードでJSON形式に変換できる JSON形式のnamedValues、もしくは、配列のvalues
処理するApps Scriptが記述するスクリプトディター Googleフォームから起動 Googleスプレッドシートから起動
メリット 回答を編集するURLなど、Googleフォームで管理する情報を参照できる 回答データを簡単に参照できる
デメリット 回答データを参照するのにひと手間かかる Googleフォームで管理する情報を参照できない

Googleフォームのフォーム送信イベント

回答のデータにアクセスするためにひと手間かける必要がありますが、回答を編集するためのURLなど、Googleフォームで管理しているすべての情報にアクセスすることができます。

利用するためには、Googleフォームからスクリプトエディターを起動します。

Screenshot 2022-12-18 08.10.42.png

フォーム送信イベントを受け取るために、スクリプトエディターでトリガーを設定します。「イベントのソースを選択」は「フォームから」にします。

image.png

フォーム送信イベントから回答データを参照するには、FormResponseクラスresponse属性にアクセスします。ただ、フォームの種別ごとにクラスが分かれていて、公式ドキュメントをいちいち調べる必要があります。そこで、FormResponseクラスをJSON形式に変換するコードを作りました。クラスが分かれているよりはずっと使いやすいと思います。よろしければご活用ください。

フォームの種別ごとに、以下のようなJSON形式の回答データに変換されます:

{
  "記述式は?": "記述式です。",
  "段落は?": "段落です。",
  "ラジオボタンは?": "ラジオボタン1",
  "チェックボックスは?": [
    "チェックボックス1"
  ],
  "プルダウンは?": "プルダウン1",
  "均等目盛は?": "1",
  "選択式(グリッド)は?": {
    "行1": "列1",
    "行2": null
  },
  "チェックボックス(グリッド)は?": {
    "行1": [
      "列1"
    ],
    "行2": null
  },
  "日付は?": "2022-02-03",
  "時刻は?": "22:00"
}

Googleスプレッドシートのフォーム送信イベント

Googleスプレッドシートに記録される回答には簡単にアクセスできますが、回答を編集するためのURLなど、Googleフォーム側で管理している情報にアクセスすることが難しい、という特徴があります。

利用するためには、Googleフォームに紐づいたGoogleスプレッドシートからスクリプトエディターを起動します。

Screenshot 2022-12-18 08.14.11.png

フォーム送信イベントを受け取るために、スクリプトエディターでトリガーを設定します。「イベントのソースを選択」は「スプレッドシートから」にします。

Screenshot 2022-12-18 08.15.40.png

フォーム送信イベントから回答データを参照するには、namedValues属性もしくはvalues属性にアクセスします。公式ドキュメントに記載された例は次の通りです:

namedValuesはフォーム送信の質問の名前と値を含むオブジェクトです。値は配列になっています。

namedValues
{
  "First Name": ["Jane"],
  "Timestamp": ["6/7/2015 20:54:13"],
  "Last Name": ["Doe"]
}

valuesはスプレッドシートに表示されるのと同じ順序で値の配列です。

values
["2015/05/04 15:00", "amin@example.com", "Bob", "27", "Bill", "28", "Susan", "25"]

JSON形式のフォーム送信イベントならテストが楽になる

Apps Scriptが正しく動作するかテストする時に、手入力でいちいちフォームに回答するのは大変です。そこで、フォーム送信イベントを予め準備しておき、そのイベントを使ったコードをテストすると便利です。

上記したやり方だとフォーム送信イベントをJSON形式で記述できるので、テストを書くのも楽になります。

以下は、フォームへの回答をSlackやGoogle Chatに送信する例です。

Googleフォームのフォーム送信イベントのテスト

onFormSubmit()でフォーム送信イベントを受信して、handleResponse_()で通知します。onFormSubmit()こちらのコードを使い、フォーム送信イベントをJSON形式に変換しているのがポイントです。

testNotify()はフォーム送信イベントをJSON形式で受信したものとして記述しています。testNotify()を実行するだけでSlackやGoogle Chatへの通知をテストできます。

// SlackやGoogle Chatへ通知
const WEB_HOOK_URL = 'https://chat.googleapis.com/v1/spaces/xxx/messages?key=xxx&token=xxx';
function notify(text) {
  const response = UrlFetchApp.fetch(WEB_HOOK_URL, {
    method: 'post',
    headers: {
      contentType: "application/json; charset=UTF-8"
    },
    payload: JSON.stringify({ text })
  });
  console.log(response);
}

// Googleフォームの送信イベントをJSON形式に変換
// https://qiita.com/takatama/items/d5ae76811ff96f34114b
// トリガーにこの関数を設定する
function onFormSubmit(e) {
  ...
  handleResponse_(items);
}

// フォーム送信イベントを処理(Google Chatに通知)
function handleResponse_(items) {
  const text = JSON.stringify(items, null, 2);
  notify(text);
}

// SlackやGoogle Chatへ通知するテスト
function testNotify() {
  const items = {
    "email": "hogehogefugafuga@example.com",
    "氏名": "ほげほげ ふがふが",
    "種別": "業務開始",
    "時刻": "9:00"
  };
  handleResponse_(items);
}

Googleスプレッドシートのフォーム送信イベントのテスト

前記したコードに対してonFormSubmit(e)だけが異なります。フォーム送信イベントのnamedValuesを参照し、値を配列から文字列に変換しています。他の関数は同じなので省略します。

// トリガーにこの関数を登録する
function onFormSubmit(e) {
  const v = e.namedValues;
  const items = {}
  Object.keys(v).forEach(key => items[key] = v[key].join(','));
  handleResponse_(items);
}

こちらもtestNotify()を実行するだけでSlackやGoogle Chatへの通知をテストできて便利です。

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?