用Clasp開發Google Apps Script網頁應用

clasp是command line工具可以管理Google Apps Script項目,專案網址: https://github.com/google/clasp 後面會將Google Apps Script的項目簡稱為script。

本篇2021/10/8內容與排版重新處理過。

安裝clasp

先安裝npm再把clasp安裝到全域環境,以Ubunt 20.04為例

sudo npm install -g @google/clasp

啟用Script API並登入clasp

  1. 進入 https://script.google.com/home/usersettings 將Google Apps Script API啟用。

  2. 登入clasp

    clasp login

    會開啟瀏覽器要求你登入google帳號,接著會需要同意用clasp來管理你的google帳號。

建立Script項目

使用clasp開發Script有兩種初始方法

  1. 由clasp建立webapp

    clasp create --type webapp
  2. 拷貝既有script

    可指定或不指定script id

    1. clasp clone

      可用游標選單選擇要開啟的Script,只是要注意會被列出的項目,並沒有包含Doc或Sheet裡面開指令碼編輯器的項目。所以若有發現少項目就是因為這樣。

    2. clasp clone <script id>

      由可存取script將程式碼和設定都抓下來

上述兩種建立方法都會在當前目錄產生數個檔案

  • appscript.json 內容如下:

     {
      "timeZone": "America/New_York",
      "dependencies": {
      },
      "exceptionLogging": "STACKDRIVER",
      "runtimeVersion": "V8"
     }
    
  • .clasp.json 內容如下

      {"scriptId":"1HBl...PKB","rootDir":"/storage/my-script-project"}
    

    clasp指令用這個檔案判斷該對哪個是Script項目進行操作的。
    rootDir可以不用寫完整路徑,整個去掉的話代表當前目錄

  • js檔案

    Script項目中的指令碼檔案,在clasp載回來副檔名是js,但是在線上編輯器會寫gs。

  • html檔案

    Script項目中的html檔案。

clasp指令

我自己操作指令後,覺得直接看怎麼發布版本就好了。

常用的指令

  • clasp push 將檔案放到script伺服器上,在push時會做語法檢查。push之後網頁編輯器需要回到列表再點script項目;直接重刷網頁編輯器常常不會載入新push的程式碼。
  • clasp versions 查看所有版本。
  • clasp version 命名版本。
  • clasp deployments 查看所有部屬。
  • clasp deploy 部屬目前版本。

我沒在使用的指令

  • clasp pull 將script伺服器上的程式碼拉下來。--versionNumber 可指定版本號碼。
  • clasp open 會開啟你的瀏覽器載入目前Script項目的網頁編輯器。
  • clasp status 檢查目前目錄下檔案跟伺服器上檔案的變化。
  • clasp run 是用dev模式跑function的,並不是跑整個script項目。
  • clasp logs 這個指令需要連結GCP的專案才能用。

刪除Script

這部份沒辦法用clasp來做。你要刪除專案你要進入AppsScript網頁,從我的專案裡面選擇要刪除的Script項目,然後點選左邊工具列總覽,右上方永久刪除專案。這時候會有大約30天的會在垃圾筒裡,你真的很需要立刻刪除再進去把它真的刪除掉。

發布版本

一般作法

  1. clasp push 將程式碼推上伺服器
  2. clasp version 為推上伺服器的版本命名
  3. clasp deploy 部屬這個版本

然後deploy會顯示一個長的像AKfy...-3g的deploy id你可以用它存取web app https://script.google.com/macros/s/{DEPLOY_ID}/exec

我們的作法

先用clasp deploy兩次產生兩個deply id。

  • 一個作為production使用
  • 一個作為development使用。

你或許會覺得奇怪為什麼不用Script本身的測試部屬,這是因為測試部屬有些處理跟deploy結果並不一致,所以乾脆就用兩組。

  • clasp push & clasp deploy --deploymentId <deploy id-1> --description "release@$(date)"
  • clasp push & clasp deploy --deploymentId <deploy id-2> --description "development@$(date)"

先push再deploy,指定deploy到哪個id並自動取時間為deploy版本命名(吐槽:指令明明是寫description描述)。

範例

index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    hello world
  </body>
</html>

web.gs

function doGet() {
    return HtmlService.createTemplateFromFile('index').evaluate();
}

看request用

function doGet(request) {
    return HtmlService.createHtmlOutput(JSON.stringify(request));
}

function doPost(request) {
    return HtmlService.createHtmlOutput(JSON.stringify(request));
}

用Sheet做Access Log

function doGet() {
  SpreadsheetApp.getActiveSheet().appendRow(['GET', new Date()]);
  return HtmlService.createTemplateFromFile('index').evaluate();
}

使用getActiveSheet()需要是Sheet裡面開指令碼編輯器才能這樣用。 如果是獨立的sheet就要看指定sheet和sheet名稱,如下:

function doGet() {
  SpreadsheetApp
    .openByUrl('https://docs.google.com/spreadsheets/....');
    .getSheetByName('工作表1')
    .appendRow(['GET', new Date()]);
  return HtmlService.createTemplateFromFile('index').evaluate();
}

留言