羊毛 | 寫 Code 雜談

願如同童話裡的山羊般咀嚼知識

0%

Google Apps Script 建立簡易後端(一)

前陣子基於興趣研究了 Google App Script (aka. GAS) 這個 Google 的服務,類似 microsoft 旗下 office 系列的 VBA。研究過程發現 GAS 有接收 http request 的功能,就想到能不能弄出用 Google SpreadSheet 當資料庫,GAS 當後台的網頁呢?

[正文]

在這一篇文章中,將會依序學到這些

  • 如何建立一個 Google Apps Script Project
  • Google Apps Script 取得及回應 HTTP Request 的方法
  • 部屬 Google Apps Script Web App 的設定與其差別
  • Google Apps Script Project 的簡單範例

在讀這篇文章之前,應該要先具有以下條件在閱讀會比較好:

  • 有一個 Google 帳號,且會使用 Google Services,如:Spreadsheets;
  • 對於 HTML5 + CSS3 + JavaScript 的基本認知( 能看得懂,會寫更好 );
  • 知道 HTTP GET Request 和 HTTP POST Request 的差別點

先進入 Google Drive 來創立一個 Google Apps Script Project

不過第一次新增是不會有 Google Apps Script 的選項,所以要先選擇最下面的 Connect more apps 來新增想連結帳戶的應用程式。

右上角的收尋框輸入 Google Apps Script 第一個就是了,然後直接按下 CONNECT!

可能會出現一個選項,主要是在說使用 Google Drive 時這個 APP 能開啟的檔案都預設成用這個 APP 開啟,勾不勾選都沒關係,不會造成影響。直接按下 OK 就好。

再去新增裡找看看,就會發現多了 Google Apps Script 拉,大力的點下去就對了!

看到這個畫面,代表已經進入 Google App script 開發的大門內搂~ 最重要的第一步是先為這個專案命名,然後時常保持 Ctrl + S 存檔的習慣。


根據 GAS Web App 的說明,GAS 在

  • 收到 HTTP GET Request 後會去執行 doGet(e) ;
  • 收到 HTTP POST Request 後會去執行 doPost(e) ;

我們將直接實作 Get Request 的部分,POST Request 的部分和 GET Request 差不多,就自行發揮 ( 在最下面有 Example Code )。

myFunction() 之後用不到,可以直接刪除或替換成 doGet(e)。而 doGet(e) 的 e 是一個儲存 Request 資料的結構。文件很清楚的寫著 e.parameter 存了 Get 傳遞的資料。

如果 GET Request URL = https://script.google.com/.../exec?name=WooLNinesun&age=1000
則經由下面的 Example Code 可以輕鬆的取得 GET Request 的傳遞參數

GAS.gs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
e = {
"queryString": "name=WooLNinesun&age=1000",
"parameter": {
"name": "WooLNinesun",
"age": "1000"
},
......略
}
*/

function doGet(e) {
// Get params
var param = e.parameter;
var name = param.name;
var age = param.age;
// do something...
}

很好!我們現在學會了接收傳進來的資料,假設現在我們要將傳進來的資料做一些處理,例如讓自己永遠 18 歲 ( 假資料 4 ni ?! ),然後把資料展示傳回給請求端。

根據 GAS Web App 的說明,我們可以用 HTML service ( 回傳 html 頁面 ) 或 Content service ( 回傳純資料 ) 把資料展示回傳給請求端。以下將直接示範三個例子。

Returning Plain Text

我們直接使用 Content service 的 ContentService.createTextOutput();

GAS_Plain_Text_output.gs
1
2
3
4
5
6
7
8
9
10
11
12
function doGet(e) {
// Get params
var param = e.parameter;
var name = param.name;
var age = param.age;
// Change age to 18th
age = 18;
// Set return string
var result = "name is " + name + ", age is " + age + " th.";
// Return
return ContentService.createTextOutput( result );
}

Returning JSON

若是想要將資料轉換成常用 json 格式的話,使用 JSON.stringify() 就能夠輕鬆的搞定

GAS_JSON_output.gs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function doGet(e) {
// Get params
var param = e.parameter;
var name = param.name;
var age = param.age;
// Change age to 18th
age = 18;
// Set return object
var result = {
name : name,
age : age
};
// Set object to json string
var JSONString = JSON.stringify(result);
// Return
return ContentService.createTextOutput(JSONString)
.setMimeType(ContentService.MimeType.JSON);
}

Returning HTML

如果想要直接回傳一個 html 介面,就要使用 HTML service 拉,不過看到這種 html + css + js 夾雜的 code 會想吐血就是了。

GAS_HTML_output.gs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function doGet(e) {
// Get params
var param = e.parameter;
var name = param.name;
var age = param.age;
// Change age to 18th
age = 18;
// Set return html string
var HTMLString = "<style> h1,p {color: red;}</style>"
+ "<h1> Name is " + name + "</h1>"
+ "<p> Age is " + age + "</p>"
// Return
return HtmlService.createHtmlOutput(HTMLString);
}

就這樣學會了可以接收資料和展示回傳資料的功能,接下來會說明如何測試和部屬 Web App 。測試的部分,我們只要建立一個函數去呼叫 doGet(e) 就可以了,例如

GAS.gs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function doGet(e) {
// Get params
var param = e.parameter;
var name = param.name;
var age = param.age;
// do something...
}

function debug() {
var e = {
"queryString": "name=WooLNinesun&age=1000",
"parameter": {
"name": "WooLNinesun",
"age": "1000"
}
}
// call doGet function
var result = doGet(e);
//logger
Logger.log("%s" ,result );
}

然後在 Select function 的地方選擇 debug ,在按下 Debug ( 蟲蟲 ) 或 Run ( 向右三角形 ) 就會開始執行瞜,途中發生錯誤就會停下並告知。

當測試結束沒問題時就可以部屬 Web App 拉,Publish -> Deploy as web app ……

 

  • Project version: 選擇要部屬儲存的哪一個版本。( 詳細說明就不多做解釋了 )
  • Execute ths app as: 選擇執行 App 的身分為何,選項有
    • Me(…) 是自己,意思是讓任何可以 Access 的人以你的身分執行你寫的 GAS
    • User accessing thw web app 是其他可以 Access 且有登入的的使用者。
  • Who has access to the app: 誰可以 access 你寫的 GAS,可以是
    • only myself ( 只有自己 )
    • anyone ( 任何有登入的使用者 )
    • anyone, even anonymous
      ( 任何人,含未登入,只有在 Execute ths app as 選擇 Me(…) 的時候會出現。 )

設定好後,按下 Deplay  後應該會得到一串網址長得像下面這樣

https://script.google.com/macros/s/GASID/exec  ( GASID 每個人都不一樣 )

這就是 Web app 的網址 ,不同部屬設定有不同的應用方式,以下是一些範例

EX1. GAS_HTML_output.gs (上面的範例)

部屬設定為:

  • Execute ths app as: User accessing thw web app
  • Who has access to the app: anyone 

https://script.google.com/macros/s/GASID/exec?name=WooLNinesun&age=1000

就會變成只有有登入的使用者他們自己的身分去執行 App,然後得到一個網頁~ 未登入的使用者會被要求登入。

EX2. GAS_Plain_Text_output.gs (上面的範例)

部屬設定為:

  • Execute ths app as: Me(…)
  • Who has access to the app: anyone 

https://script.google.com/macros/s/GASID/exec?name=WooLNinesun&age=1000

就會變成只有有登入的使用者我的身分去執行 App 然後得到一串 String。

EX3. GAS_JSON_output.gs (依然上面的範例)

部屬設定為:

  • Execute ths app as: Me(…)
  • Who has access to the app: anyone, even anonymous

https://script.google.com/macros/s/GASID/exec?name=WooLNinesun&age=1000

就會變成任何人使用我的身分去執行 App 然後得到一串 Json String。

EX4. GAS_POST_Input.gs (Example code)

部屬設定為:

  • Execute ths app as: Me(…)
  • Who has access to the app: anyone, even anonymous

Run example.4 code in jsbin
因為是 POST Request,沒辦法簡單的用 URL 去實作資料傳遞,所以用 JSBin 去提供執行環境。右上角的 run 按下去就會向 GAS 發出一個 POST Request 搂。

以上就是簡單的四個範例,可以試試看將開啟的連結拿去無痕式的視窗開啟,看看差異。

[總結]

本篇主要重點在於用 GAS 建立一個小型的 Web App 後端,其最大的用途不是可以輸出 html 檔,而是利用 GAS 可以結合其他 Google Service 的服務,像是 Spreadsheets ( 試算表 )、Drive ( 雲端硬碟 ) 或 Photo ( 照片 ),進而利用 Ajax 技術來存取各項資料。比如說今天用 ajax 向一個 GAS 發出 name=WooLNinesun 的 GET  Request,GAS 接收到資料後,開啟名為 UserData 的 Spreadsheets  取出對應的 age 資料,然後在回傳。這樣就形成了簡單的資料庫瞜!下一篇會介紹 GAS 如何存取其他 Google Service 的服務 ~