I/O 2013のGoogle Apps Script Update その1 Form上のGASとFormApp

# I/O 2013の Google Apps Script更新

Google Apps(Google DocumentsやGoogle Spreadsheetなど)のマクロ環境である、
Google Apps Script(通称GAS)が、2013/5/15から開催される、
Google I/O 2013に向けて、大幅アップデートされました。

___公式記事___
[New Apps Script features](http://googleappsdeveloper.blogspot.com/2013/05/new-apps-script-features-at-google.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+GoogleAppsDeveloperBlog+%28Google+Apps+Developer+Blog%29)

# ざっくりな更新の概要

今回のアップデートではざっくり以下が更新となりました。

* Google Forms上でGoogle Apps Scriptの利用が可能に
* Google Documents上でGoogle Apps Scriptの利用が可能に
* Google Formsを操作するためのAPI、 FormAppが追加
* 新しいGoogle DriveのAPIに対応した、DriveAppが追加
* HTMLでUI作成するためのHtmlServiceをより早く動かすためのSandboxモードが追加
* Google API Consoleを利用した新しいAPI認証方式が追加

特に、この「Google Forms」周りに関しては、今までFormsを扱うためのWeb APIが存在しなかったため、
唯一Google Formsを扱うことが出来る環境として、期待ができます。

今日から何回かに分けて、今回の更新についてQiitaで書いて行きたいと思います。
多分( ｰ`дｰ´)ｷﾘｯ

# Forms上のGASとFormApp

ということで今回はForm上で動かすことが可能になったGASの機能と、
Formsを操作するためのFormAppについて簡単にですが書いて行きたいと思います。

## Formsとは？

Google Formsはイベントの計画、アンケートの送信、学生への小テストの出題、その他の情報収集を簡単かつ効率的に行える便利なツールです。 ※GoogleのHelpより引用

ユーザはGoogle Drive上から簡単にアンケートフォームを作成することができ、  
収集した結果をグラフ表示したりできます。

昔はGoogle Spreadsheetの機能の一つとして、データがGoogle Spreadsheet上に溜まっていっていたのですが、最近の更新でGoogle Formsが独立し、Google Formsのみで、データを貯められるようになりました。

また、近いうちにFusion Tablesというデータベースにデータをタメられるようになるようです。

## Forms上のGoogle Apps Script

DriveからFormsを作成し、「ツール」→「スクリプト エディター」からForms上で動作するGASを作成することが出来ます。

### トリガー

Forms上のGASでは、以下の特殊なトリガーを作成することができます。

* Formsの項目作成エディタを開いた際に起動するトリガー
* Formsでユーザが回答した際に起動するトリガー(ただしコチラはSpreadsheetからも設定可能)

### FormApp

Formsの質問項目を操作したり、回答内容を操作するためには、FormAppというGASのサービスを利用します。

___FormAppのリファレンス___
https://developers.google.com/apps-script/reference/forms/

ざっくりできる事を書きますと、

* Forms自体の取得、作成
* Formsの質問項目の取得、追加、修正
* Formsの回答の取得、追加、修正
* Formsのその他設定系（説明文や、グラフの公開状態等)情報の取得、設定
* Formsの項目エディタ上でメニューの追加、ダイアログ・サイドバーUIの作成

ができます。

#### Forms自体の取得、作成

Formsの項目等をいじるためにはForms自体を取得する必要があります。
Formsを取得する方法は以下の三種類が現状用意されています。

```javascript:フォームの取得.js
function getFormInstance() {
  //現在表示ているまたは、トリガー時に動作しているフォームを取得
  var form = FormApp.getActiveForm();
  
  //URLに記載されているkeyパラメータを利用して取得
  var formA = FormApp.openById("url上のkeyパラメータ");
  
  //URLを利用して取得
  var formB = FormApp.openByUrl("URL");
}
```

また作成する場合は、以下のようにcreateメソッドを利用します。

```javascript:formの作成
function createNewForm() {
  var form = FormApp.create('フォームのタイトル');
}
```

#### Formsの質問項目の取得、追加、修正

Formsに質問を追加修正削除するには以下のようにします。

```javascript:フォーム項目の追加_取得_修正_削除.js
function フォーム項目の追加_取得_修正_削除() {
  var form = FormApp.getActiveForm();
  
  var textItem = form
  .addTextItem() //フォームにテキスト形式の質問を追加
  .setTitle('質問のタイトル') //質問にタイトルを設定
  .setHelpText('質問の注意書き') //質問の注意書きを設定
  .setRequired(true) //質問が必須回答か否かを設定(trueで必須)
  ;
  
  //フォームの項目を取得
  var item = form.getItems()[0];
  
  //項目をテキスト形式として扱い、タイトルを修正
  item.asTextItem().setTitle('タイトルを修正');
  
  //項目を削除
  form.deleteItem(item);
  
  //form.moveItem(from, to)で場所を変更することも可能です。
}
```

#### Formsの回答の取得、追加、修正

Formの回答を取得するには、form.getResopnsesメソッドを利用する。

```javascript:回答周り.js
function フォームの回答周り() {
  var form = FormApp.getActiveForm();
 
  //form.getResponses()で全ての回答（FormResponseの配列）が取得できる。
  //FormResponseは各項目が全て詰まった、ユーザの回答情報オブジェクト
  //form.getResponses(new Date())などで日付を絞った回答も取得できる。
  var responses = form.getResponses();
  
  var response = responses[0];
  
  //各項目の回答情報を取得
  var itemResponses = response.getItemResponses();
  
  for(var i = 0; i < itemResponses.length; i++) {
    var itemResponse = itemResponses[i];
    
    //getResponseで実際の回答を取得できる。
    Logger.log(itemResponse.getResponse());
  }
  
  //回答者のメールアドレス(ただしFormsの機能を利用して収集している場合 多分Google Apps for Business等を利用している場合のみ可能)
  Logger.log(response.getRespondentEmail());
  
  //回答時間
  Logger.log(response.getTimestamp());
  
  //編集用のURL これも許可している場合のみ?
  Logger.log(response.getEditResponseUrl());
  
}
```

#### Formsのその他設定系（説明文や、グラフの公開状態等)情報の取得、設定

Formオブジェクトにはその他、設定系のメソッドも用意されています。
数が多すぎなので、補完機能で見てみて下さい。

#### Formsの項目エディタ上でメニューの追加、ダイアログ・サイドバーUIの作成

個人的には最も熱い機能です。
GASを利用して、Forms自体にメニューを追加したり、ダイアログ・サイドバーを表示出来るようなります。

まずこの手のUI系をいじる場合は、FormAppのgetUi()メソッドを利用します。
メニューを追加する場合は、uiのcreateMenuを利用します。

```javascript:メニューの追加
  var ui = FormApp.getUi();
  ui.createMenu("メニューのタイトル")
  .addItem('メニュー内の項目名', '起動するGoogle Apps Scriptのメソッド名')
  .addToUi();
```

ダイアログや、サイドバーを作成する場合は、uiのshowDialog、showSidebarメソッドを利用します。
これらのメソッドはHtmlServiceのHtmlOutputまたは、UiAppのUiInstanceを引数に渡します。

```javascript:ダイアログの表示.js
function showDialogByHtml() {
  var ui = FormApp.getUi();
  
  ui.showDialog(HtmlService.createHtmlOutput("<p>コンテンツ</p>").setTitle("タイトル"));
}

function showDialogByUiApp() {
  var ui = FormApp.getUi();
  var uiapp = UiApp.createApplication()
  ui.showDialog(uiapp.add(uiapp.createLabel('コンテンツ')).setTitle('タイトル'));
}

function showSidebarByHtml() {
  var ui = FormApp.getUi();
  
  ui.showSidebar(HtmlService.createHtmlOutput("<p>コンテンツ</p>").setTitle("タイトル"));
}

function showSidebarByUiApp() {
  var ui = FormApp.getUi();
  var uiapp = UiApp.createApplication()
  ui.showSidebar(uiapp.add(uiapp.createLabel('コンテンツ')).setTitle('タイトル'));
}
```

あとはHtmlServiceであれば、google.script.runを利用して、gasを呼び出したり、
UiAppであれば、ServerHandlerを利用して、gasを呼び出せば、様々なことが出来るようになります。

# まとめ

いかがでしたでしょうか？
今までGoogle Formsは動的に作成したりすることが出来ず、
手で頑張って作るものでしたが、GASのFormAppの登場により様々なことが出来るようになりました。

また、getUi()周りによる、Forms自体の拡張が可能になり、Google Apps for Businessを利用している企業では、
ワークフロー用のフォーム作成などがかなり簡単になることが期待出来ます。

個人的には、もう少しTriggerが増えて、ユーザごとに説明文や、完了メッセージが変えられると嬉しいのですが、
その辺りは今後に期待したいです。

次回は、HtmlServiceのSandboxモードについて書きたいと思います。