GASの便利な使い方

本記事は[マイネット Advent Calender](http://qiita.com/advent-calendar/2015/mynet)8日目の記事です。
なんか空きがあったので @peto_tn が枠を頂きます。

# はじめに
弊社では多数のソーシャルゲームを運用しており、その中で使用する様々な資料やデータをSpreadSheet等のGoogle Appsを利用して管理しています。
それらをスクリプトで良い感じに制御して楽をしようとGoogleAppsScript(以下GAS)を書いているわけですが、個人的に便利だなーと思う機能をまとめていきたいと思います。

# SpreadSheetのメニューバーに機能追加
スプレッドシートに紐づいたGASを利用して、メニューバーから直接関数を実行できるようにします。

```js:addMenuBar
function showDialog()
{
  Browser.msgBox("メニューバーに追加したで");
}


/**
 * 起動時処理
 */
function onOpen() {
  // メニューバーにカスタムメニューを追加
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [
    {name : "ダイアログを表示"  , functionName : "showDialog"},
  ];
  spreadsheet.addMenu("追加メニュー", entries);
}
```
onOpenでスプレッドシートが起動したトリガーを拾います。
entriesに{name : 表示名  , functionName : 関数名}でspreadsheetオブジェクトにaddMenuできます。

# GoogleDriveにCSV出力
スプレッドシートを使ってるとcsvで出力したくなると思います。
標準でもcsv出力機能は備わっているのですが、余分なものまで吐かれたり、文字コード指定ができなかったりします。
GASで書くと痒いところまで手が届く実装が可能です。

```js:outputCsv
/**
 * csv出力(UTF8)
 * @param rootDirId ルートディレクトリのID
 * @param path      出力パス(/区切り)
 * @param fileName  ファイル名
 * @param data      出力データ(data[row][column]2次元配列)
 */
function outputCsv(rootDirId, path, fileName, data) {
  // 定数
  var contentType   = "text/csv";
  var charSet       = "UTF8";
  var lineDelimiter = ",";
  var newLineChar   = "\n";
  
  // 出力先取得
  var paths = path.split('/');
  var root  = DriveApp.getFolderById(rootDirId);
  var dir   = root;
  for (var j = 0; j < paths.length; j++) {
    dir = dir.getFoldersByName(paths[j]).next();
  }
  
  // 2次元配列になっているデータをcsvのstringに変換
  var csvString = underscoreGS._map(
    data,
    function(row){
      return row.join(lineDelimiter); // 行結合
    }
  ).join(newLineChar); // 列結合
  csvString += newLineChar;
  
  // Blobに変換
  var blob = Utilities.newBlob("", contentType, fileName).setDataFromString(csvString, charSet);
  
  // 既存ファイルを削除
  var fileIterator = dir.getFilesByName(fileName);
  if (fileIterator.hasNext()) {
    dir.removeFile(fileIterator.next());
  }
  
  // Blobをファイルに出力
  dir.createFile(blob);
}
```
rootDirIdで出力先の起点となるディレクトリのIDを受け取り、pathで指定されたディレクトリをgetFoldersByNameを繰り返し実行して特定しています。
その後UtilitiesのnewBlob関数でblobを作成し、setDataFromString関数で文字コードを指定してデータを設定しています。
ついでに、GoogleDriveは同名ファイルを許容するのでgetFilesByNameで取得できた同名ファイルが存在する場合、（ひとつのみ）削除処理をいれて出力することで、ファイル更新をしているように見せかけています。

# 実行可能APIの作成
一度作ったスクリプト何度も使いまわしたいことがあると思います。
GASには作成したスクリプトをAPIとして公開できる機能があるのでとても便利です。

## APIを公開
メニューバー→公開→実行可能APIとして導入　を選択  
![Imgur](http://i.imgur.com/bvpoyZO.jpg?1)
ユーザーは全員に公開に設定すると他の人にもみれます。
ビジネスアカウントの場合は、会社用アカウント内での公開となります。
  
一般アカウントの場合は以下の作業も必要です。
[GoogleDeveloperConsole](https://console.developers.google.com/apis/)にアクセスし、「Google Apps Script Execution API」を検索して、APIを有効にして下さい。

## APIを利用
メニューバー→リソース→ライブラリ　を選択
![Imgur](http://i.imgur.com/16qKqAv.png?1)
ライブラリを検索にAPI IDを指定して選択して下さい。
識別子は、スクリプト内で使用する際のオブジェクトの文字列になります。デベロッパーモードを有効にすると、APIの公開状態に関わらず最新のコードが使用されます。

```js:sample
function myFunction() {
  var data = [
    [1,2,3],
    [4,5,6]
  ];
  csv.outputCsv('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'test', 'test.csv', data);
}
```

# おわりに
わざわざ環境を用意する必要がなく、非常に簡単に実装/公開ができるのがGASの大きな魅力です。
面倒なことはどんどんGASに押しつけて楽をしていきたいですね。
GASを使うとChatOpsや簡単なWebサーバーなども実現できたりとまだまだ便利なことがあるので、また機会があれば書きたいと思います。