Googleフォームって便利ですよね。「何をどう回答すればよいか」が一目で分かるので、回答する人が迷わず入力できます。
ただ、フォームに回答があったことの通知はとてもお粗末です。フォームの設定からメールで通知できるのですが、メール本文には「回答がありました」という一言と回答結果へのリンクが掲載されているだけ。どんな回答があったのかを知るためには、リンクをわざわざクリックしなければなりません。
そこでよくやるのが、Apps Scriptを使った通知のカスタマイズです。フォーム送信イベントをトリガーにしてApps Scriptを起動し、通知内容をいい感じに整えたり、通知先をSlackやGoogle Chatに変更します。
このフォーム送信イベントですが、回答を保存する場所に応じて、Googleフォームのイベントと、Googleスプレッドシートのイベントの2種類があります。この記事では、それぞれのイベントについて解説します。また、Apps Scriptのテストを楽にする方法も追記します。
回答を保存する場所に応じて2種類あるフォーム送信イベント
Googleフォームへの回答は、もちろん、Googleフォームに保存されます。さらに、Googleスプレッドシートを紐づけて、そちらにも保存することもできます。スプレッドシートへの紐づけは、フォームの回答タブの右上にあるスプレッドシートアイコンをクリックすると実行できます。
回答を保存する場所に応じて、フォーム送信イベントがそれぞれ準備されています。イベントを処理する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フォームからスクリプトエディターを起動します。
フォーム送信イベントを受け取るために、スクリプトエディターでトリガーを設定します。「イベントのソースを選択」は「フォームから」にします。
フォーム送信イベントから回答データを参照するには、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スプレッドシートからスクリプトエディターを起動します。
フォーム送信イベントを受け取るために、スクリプトエディターでトリガーを設定します。「イベントのソースを選択」は「スプレッドシートから」にします。
フォーム送信イベントから回答データを参照するには、namedValues
属性もしくはvalues
属性にアクセスします。公式ドキュメントに記載された例は次の通りです:
namedValues
はフォーム送信の質問の名前と値を含むオブジェクトです。値は配列になっています。
{
"First Name": ["Jane"],
"Timestamp": ["6/7/2015 20:54:13"],
"Last Name": ["Doe"]
}
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への通知をテストできて便利です。