GoogleAppsScript
GoogleSpreadSheet
googleform

GASのonFormSubmit()でハマったこと

フォームから回答が送信されたら自動的に色々処理を行うスクリプトをスプレッドシート側で書いていた時にハマったことを記録しておきます。

やろうとしたこと

(1)フォームから回答が流れてくる
(2)トリガ設定をフォーム送信時に設定したonFormSubmit(event)を起動
(3)event.responses.getItemResponses()で回答の配列を得る
(4)得たデータの特定要素の内容によって他のシートにデータをコピーする

具体的には送信者の所属によってデータを書き出すところを変えてまとめておきたかったのです。

エラー内容

実行に失敗: TypeError: undefined のメソッド「getItemResponses」を呼び出せません。

そもそもgetItemResponses()が呼び出せていません。つまりresponsesは存在しないことになっています。おかしいなあリファレンスもちゃんと見たのになあ〜

原因

ではリファレンスをもう一度見てみましょう。onFormSubmit()は二種類あります。

Google Sheets Event

Form submit

  • authMode
    A value from the ScriptApp.AuthMode enum
FULL
  • namedValues
    An object containing the question names and values from the form submission
{
  'First Name': ['Jane'],
  'Timestamp': ['6/7/2015 20:54:13'],
  'Last Name': ['Doe']
}
  • range
    A Range object, representing the cell or range of cells that were edited
Range
  • triggerUid
    ID of trigger that produced this event
4034124084959907503
  • values
    Array with values in the same order as they appear in the spreadsheet
['2015/05/04 15:00', 'amin@example.com', 'Bob', '27', 'Bill',
'28', 'Susan', '25']

Google Form Event

Form Submit

  • authMode

    A value from the ScriptApp.AuthMode enum

    FULL
    
  • response

    A FormResponse object, representing the user's response to the form as a whole

    FormResponse
    
  • source

    A Form object, representing the Google Forms file to which the script is bound

    Form
    
  • triggerUid

    ID of trigger that produced this event

    4034124084959907503
    

今回僕が利用しようとしていたのはGoogle Form events側のonFormSubmitです。しかしundefinedエラーを食らったので、responseが存在しないGoogle Sheetsevents側のonFormSubmitを呼び出していたのではないかと考察できます。ここで原因がわかりました。僕が冒頭に言ったことを覚えていますか?今回のスクリプトを「スプレッドシート側で書い」たのです。つまりresponseプロパティを持つonFormSubmitを使うためには、「フォーム側で」スクリプトを書かなければいけなかったのです!

コード修正

勘違いしていた部分

function onFormSubmit(event){
  var itemResponses = event.response.getItemResponses();

  var bureau = itemResponses[0].getResponse();
  var name = itemResponses[1].getResponse();
  var email = itemResponses[2].getResponse();

  categorizer(bureau, name, email);
  sendToUser(name, email);
}

Sheets eventsのonFormSubmitで利用できるよう書き直したもの

function onFormSubmit(event){
  var itemResponses = event.values;

  var bureau = itemResponses[1];
  var name = itemResponses[2];
  var email = itemResponses[3];

  categorizer(bureau, name, email);
  sendToUser(name, email);
}

valuesなら生データが配列としてそのまま使えるので逆にすっきりしましたね。

おわりに

GASでイベントトリガを使うときはどこでスクリプトを書いているのかしっかり意識したうえで書きましょう!!