iT邦幫忙

2025 iThome 鐵人賽

DAY 5
0

回想當初剛開始寫GAS專案時,不知道為什麼對於「內建的triggers」這個概念有點想不通,it works fine,但就說不出哪裡怪。直到實作doGet時才突然搞懂:啊,就只是這樣嘛!

前言

GAS環境有一些保留函式(reserved functions),它們既不是昨天(Day04)提到的Google Workspace API,也不屬於前天(Day03)提到的GAS環境特有的全域變數,今天就讓我簡單聊聊這些simple triggers。[^1]

正文

在瀏覽器環境,我們會設計UI與listener/handler;在GAS環境,有一些事件[^2]不需要開發者手動於UI綁listener,這類simple triggers就類似瀏覽器環境的handler。相較其它服務,其權限較小,從而也不需要額外設定或產生同意確認彈窗。

比如使用者開啟Google Sheets[^3],或開發者於Node.js環境向Google Sheets發送HTTP GET請求,GAS環境會搜尋專案內是否有對應的triggers,如果有就會call它們。

換言之,這些simple triggers都是GAS環境的保留函式,必須由開發者自行宣告由GAS指定的、保留的trigger名稱,當事件發生時,才能被invoke。而且,必須宣告於top-level,也就是triggers必須位於global scope。

其中,onEditonOpen幾乎在每個專案中我都會使用到,這邊是曾經實作過的例子:

使用onOpen來載入native-like選單:

function onOpen() {
  const ui = SpreadsheetApp.getUi();
  ui.createMenu("綜合檢視")
    .addItem("綜合標示", "highlight")
    .addItem("清除所有標示", "clearHighlight")
    .addToUi();
}

使用onEdit來記錄特定欄位之最後編輯時間:

function onEdit(e) {
  const range = e.range;
  if (
    range.getNumColumns() !== 1 ||
    range.getColumn() !== 3 ||
    range.getRow() === 1
  ) {
    return;
  }

  const currentTime = new Date();
  const targetCell = range.offset(0, -2);
  targetCell.setValue(currentTime);
}

同樣是simple triggers,doGetdoPost則必須將GAS專案部署為Web App,當外部環境向Web App[^4]發起HTTP GET或POST請求時,才會去call它們。

function doGet(event) {
  try {
    return ContentService.createTextOutput(
      JSON.stringify({
        status: "ok",
        code: 200,
        message: "The secret meetup spot of the Deno cult retrieved successfully",
        data: {
          meetupSpot: denoland,
        },
      })
    ).setMimeType(ContentService.MimeType.JSON);

  } catch (error) {
    return ContentService.createTextOutput(
      JSON.stringify({
        status: "error",
        code: 500,
        message: `Unexpected error: ${error.message}`,
      })
    ).setMimeType(ContentService.MimeType.JSON);
  }
}

總之,GAS環境提供一些保留函式,除了使用者操作觸發,也可以部署成APP並透過保留函式自定義要回傳的值。

後話

回想當初剛開始寫GAS專案時,不知道為什麼對於「內建的triggers」這個概念有點想不通,會用是會用,但就說不出哪裡怪。直到實作doGet時,在GAS環境與Deno環境分別寫了腳本串接資料,才遲遲意識到,其實它就只是一個「指定好名稱的callback function」,有一種把散亂的拼圖連接起來的感受。

我覺得挺有趣的是,查了一下,才知道原來更早的年代,瀏覽器環境也有過onloadonerror這種保留函式,那時addEventListener甚至還沒被開發者們普遍使用。

Annotations

[^1]: https://developers.google.com/apps-script/guides/triggers

[^2]: 順道一提,不影響寫專案的冷知識:不同於瀏覽器環境,GAS環境的event並非WHATWG DOM Event API標準的instance,而是JSON-like object。

[^3]: 這些simple triggers主要是對應使用者於GUI上的操作,對於GAS腳本所觸發的事件則否。

[^4]: 還有另一個部署選項是Execution API,讓外部環境可以使用專案內的函式,但需要設定OAuth。


上一篇
Day04|Google Sheets相關服務
下一篇
Day06|本地開發GAS專案:clasp簡介
系列文
我只是不想加班:一名客服人員的GAS自救之路6
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言