GASのExecution APIを使ってGASを外部からぶっ叩く


こんにちは
slackAppが意外と使われてて、メンテしなきゃいけない気がしてgkbrしている大橋です。

先日GASで定義した関数群をREST経由で叩くことができるExecution APIが公開されました。

* 概要
	* https://developers.google.com/apps-script/guides/rest/
* 公式ブログ
	* http://googleappsdeveloper.blogspot.jp/2015/09/run-apps-script-code-from-anywhere.html 




これができたことにより様々なマクロ処理をGASで定義しておき、
他のアプリケーション、例えばExcel VBAや、shell、AndroidやiPhoneのアプリケーションから呼び出すことが可能になります。
(GAS for Androidも期待できますね)

今回はこのExecution APIのサンプルを動かしてみたいと思います。


## ざっくり手順

1. GASで関数作る
2. 外から叩ける様に設定する
3. Developer ConsoleでExecution APIを使える状態にする
4. Client IDを発行
5. 4.のClient IDを使ってTokenゲッチュしてREST APIを叩く
 

です。

# やってみる

## GASの関数を作る

まずGASで外から叩く関数を作ります。
とりあえず https://script.google.com から新しいGASプロジェクトを作成します。

新しいGASプロジェクトを作成したら以下のコードを記述します。
なおこのコードはsampleそのままです。

```javascript:code.gs
/**
 * Return a list of sheet names in the Spreadsheet with the given ID.
 * @param {String} a Spreadsheet ID.
 * @return {Array} A list of sheet names.
 */
function getSheetNames(sheetId) {
  var ss = SpreadsheetApp.openById(sheetId);
  var sheets = ss.getSheets();
  return sheets.map(function(sheet) {
    return sheet.getName();
  });
}
```

## 外から叩ける様に設定する

通常のスクリプトを勝手に外から叩かれるといろいろセキュリティ的に困るので、明示的に外部からの起動を許可する必要があります。

Script Editorのメニューから「公開」→「実行可能APIとして導入...」を選択し、
バージョン欄にバージョンの詳細を記入、
スクリプトにアクセスできるユーザーを`自分のみ`に選択して「`導入`」ボタンをクリックします。

登録後 **現在のAPI ID** が表示されるのでどこかにメモしておいてください。


![Execution_API.png](https://qiita-image-store.s3.amazonaws.com/0/2965/0ca2c703-4ced-b6ab-bb25-beb04aaed587.png "Execution_API.png")

またこの後外部からこの関数を起動する際にOAuth2を使った認可処理を行いますがその際にscopeが必要になります。

ScopeはScript Editorのメニューから「ファイル」→「プロジェクトのプロパティ」を選択し表示されたダイアログのタブから「スコープ」を選択してください。
必要なScopeが表示されます。

![Execution_API3.png](https://qiita-image-store.s3.amazonaws.com/0/2965/fd61f1be-9f05-4eef-c173-1b212a00424e.png "Execution_API3.png")



## Developers ConsoleでExecution APIを使える状態にする

外部からExecution APIを叩くには、APIの実行許可を行う必要があります。
まず、Script Editorのメニューから「リソース」→「Developers Console プロジェクト...」を選択し *このスクリプトが現在関連付けられているプロジェクト*のリンクをクリックします。

![Execution_API4.png](https://qiita-image-store.s3.amazonaws.com/0/2965/3af2881f-ac67-49fc-6a59-0d3b31814c47.png "Execution_API4.png")


するとDevelopers Consoleが開くので左メニューの「APIと認証」から「API」をクリックして、API一覧を開きます。
検索ボックスに「Execution API」と入力し、「Google Apps Script Execution API」の行をクリックします。

その後表示される「APIを有効にする」ボタンをクリックしてAPIを有効化してください。


## Client IDを発行

次に認証用のClient IDを発行します。
Execution APIの認可処理は他のGoogle APIのOAuth2と異なり少し特殊で、
起動対象のGASプロジェクトが紐付いているDevelopers Consoleプロジェクトから
発行されたClient IDを使って発行した認証トークンのみExecution APIから起動されるGAS関数の実行権限を所持しています。
※テストに出ます。

なので必ずClient IDの発行が必要になります。

またGoogle APIを叩き慣れている人は「とりあえずAPI Explorerから叩けばいいんでしょ(ハナホジ」と考えるでしょうが、
それが不可能です。
API ExplorerではExecution APIの起動時に必ずエラーが出ます。

ではClient IDを発行していきます。
まず先ほどのDevelopers Consoleの左メニューの「APIと認証」から「認証情報」をクリックし認証情報画面を表示します。
次に「認証情報を追加」ボタンをクリックし「OAuth 2.0 クライアントID」を選択します。

![Execution API5.png](https://qiita-image-store.s3.amazonaws.com/0/2965/d3c6024a-21af-f5d2-c724-c45ae00cabe5.png "Execution API5.png")

次に認可を行う「アプリケーションの種類」を選択します。
今回はサーバサイドのウェブアプリケーションから行おうと思っているので「ウェブアプリケーション」を選択し以下を入力、作成ボタンをクリックします。

* **名前**
	* 任意な名前
* **承認済みJavascript 生成元**
	* 通常は認可を行う際のURIを設定します。
	* 今回は以下を設定します。
	* `https://developers.google.com`
* **承認済みのリダイレクト URI**
	* 認可の際のCallback URLを設定します。
	* 今回は以下を設定します。
	* `https://developers.google.com/oauthplayground`


作成を行うと **Client ID** と **Client Secret**が発行されるのでどこかにメモしておいて下さい。

![Execution_API6.png](https://qiita-image-store.s3.amazonaws.com/0/2965/e66a77de-c04a-608d-85da-a651aca175de.png "Execution_API6.png")


これで大方の準備は完了です。

## Client IDを使ってTokenゲッチュしてREST APIを叩く

準備は完了したので実際に叩いてみます。
この手のAPIを試す場合は API Eplorerを使うことが多いのですが、
Execution APIではそれが無理なため、
今回はGoogle OAuth2 Playgroundを使って実行してみたいと思います。

なお他の方法で起動する場合は、サンプルが公式ドキュメントに乗っていますので[そちら](https://developers.google.com/apps-script/guides/rest/quickstart/target-script#step_3_choose_a_quickstart)を参照してください。

ではまずOAuth Playgroundを開きます。

https://developers.google.com/oauthplayground

### Client IDとClient Secretの設定

次に先ほど発行したClient IDとClient Secretを設定します。
右上にある歯車マークをクリックし、ドロップダウンを表示、
一番下の、「Use your own OAuth credentials」にチェックを入れます。
Client IDとClient Secretの入力欄が表示されるので、
先ほどメモしたClient IDをClient Secretを入力します。
入力したらCloseボタンをクリックします。
![Execution API7.png](https://qiita-image-store.s3.amazonaws.com/0/2965/1eeebf91-8bab-2280-1715-08b2a318aa0c.png "Execution API7.png")


### Scopeの設定とAuthorize

Scopeを設定します。
左側にあるScope入力欄に先ほど保存しておいたScopeを入力し、「Authorize APIs」ボタンをクリックします。
![Execution API8.png](https://qiita-image-store.s3.amazonaws.com/0/2965/7e5c2eda-d74e-8cd3-66d4-46e4da4f5bac.png "Execution API8.png")

するとGoogleの認可画面が表示されるので次々進んでいってください。
Developers Consoleの設定がミスっているとこの辺でエラーが出ます。

### Tokenの取得

認可完了後、少し待つとOAuth2.0 Playgroundの左側のメニューがStep2になり、認可トークンの取得がおこなえるようになります。
「Exchange authorization code for tokens」をクリックして認可トークンを取得します。

![Exection API9.png](https://qiita-image-store.s3.amazonaws.com/0/2965/d39c65d9-0c7a-759b-e208-aa5b9ed24206.png "Exection API9.png")

### API叩く

最後にAPIを叩きます。

まず **HTTP Method:** をPOSTに設定
**Request URI**を以下のようにします。

`https://script.googleapis.com/v1/scripts/{{scriptId}}:run`

この`{{scriptId}}`は最初の頃にメモしておいた **現在のAPI ID** です。

次に 「Enter request body」 ボタンをクリックし、リクエストボディを以下のように設定します。

```json:requestBody.json
{
    'function': 'getSheetNames',
    'parameters': ["{{sheetId}}"],
    'devMode': true
}
```

この`{{sheetId}}`は読み取り可能な任意のスプレッドシートのIDを設定してください。

**各パラメータの説明**

* function
	* 起動するGASの関数名
* parameters
	* 関数の引数の配列
* devMode
	* 常に最新のコードで起動する場合は`true`を設定します。
	* `false`の場合は設定したバージョンのコードになります。


ここまで準備ができたら「Send the request」ボタンをクリックします。
問題がなければ、GASの関数が実行され結果が帰ってくるはずです。


## まとめ

これらのことはもともと`doGet`や`doPost`を利用しても行うことができましたが、
認証の部分をどうするかや、GAS内に1つしか`doGet`を設定できないためコードが複雑になったりしていました。

少々手順が多いように見えますが、
GASを利用した様々なAPI連携のマクロ処理を気軽に外から起動できるようになり、より様々な連携ができるようになります。

GASのさらなる連携性が高まりましたね！
ちなみに 10/9にあるGASのモクモクハンズオンイベント [GAS Station #2](http://gas-station.connpass.com/event/19933/)でもハンズオンを用意する予定です。 多分

ではよいGASライフを！