2014年3月19日 星期三

Google Apps Script使用心得

之前就有聽過google apps script能夠讓你自行撰寫程式碼,然後在google的次服器上執行,有人拿他來做監測伺服器運作是否正常的工具,有人拿來架設簡易的Web Server

前陣子我弄了一個google表單,要統計一些數據,我希望有人回覆表單的時候我能收到mail通知,所以就研究了一下FormEmailer,他可以幫我達到這個功能。

然後手上剛好接到一個案子,要寫一個盤點系統,因為有一些需求,所以我決定用google drive的試算表+google apps script來完成,會採用這種架構的主要原因是跨平台+省去UI開發,而且不用伺服器24小時運作。整個系統完成的時間大概花我一個半月吧,弄完之後有點小心得跟大家分享。

  1. 語法方面:基於javascript上的script語法,寫起來跟寫javascript沒啥差別,一切javascript的function都可以用,不過官方編輯器會有比較嚴謹的要求,例如:變數必須先宣告。
  2. 速度方面:這就是非常重要的一點了,google apps script跑起來,非常慢...,慢到什麼程度? 複製一個試算表,再改點權限,寫幾個值進去該表,可能要花10秒鐘左右。10秒鐘聽起來還好,不過檔案一多時間就變超久了,而且他有每次最大執行時間6分鐘的限制,執行超過6分鐘的function會被強制中斷,我怎麼知道我的程式跑起來會不會超過6分鐘? 被中斷之後你就知道了 XD
  3. 除錯方面:官方的編輯器有點難用,雖然提供了簡單的function提醒功能,也有debug功能,但是他的debug功能速度慢也就算了,居然沒辦法debug UI的event function,我google之後有人說善用Logger,但是Log根本沒辦法紀錄全部的東西啊...
  4. Log方面:說到log,我們當然希望他越詳盡越好,但是他的log只會提供最後一次的執行log,有時候根本不敷使用,我最後自己寫了一個log系統,把要紀錄的東西另外塞到別的試算表內...
  5. 穩定性方面:別懷疑,執行程式時的穩定性不好,這一個半月下來,大概2~3天會接到一次通知程式執行失敗的mail,所以你的程式要設計的非常有容錯能力,要可以檢查上次是否執行成功,如果失敗了要接下去跑,然後把執行次數多設幾次這樣才能確保程式都有跑完
  6. 計算額度方面:google apps script有提供每天的免費計算額度,例如:個人用戶1天1小時的計算時間,每天可以發出的200封Mail...等,可是他沒有一個介面讓你知道你今天的扣打剩多少了,只說會在接近上限時通知你,這有點麻煩,最後我還是自己寫了一個表,自動統計所有的function到底運算多少時間。
  7. API支援方面:開發這個系統時我用到大量的試算表,google drive有非常完善的權限控管功能,可以透過API任意新增或減少使用者,試算表也有類似的功能可以設定保護工作表,但是,保護儲存格範圍目前沒有相關的API,所以沒辦法用API去設定保護儲存格!!!!!,最後我的解法是把所有重要的資料都集中到某個工作表,然後保護該工作表....
  8. ImportRange功能:ImportRange可以讓你載入某個檔案的某部份資料進來,非常好用,但是如果import的層數一多,例如:載入A檔案的B資料,再用B資料去載入C資料,再用C資料去載入D資料,這樣一連串的載入之後速度就會變得非常慢....,大概超過3層以上的載入有時還會失敗,我的解法是把已經固定下來的載入資料直接寫入檔案,不讓他再去載入,這樣速度會快很多。
  9. 驗證資料功能:千萬別開啟驗證資料失敗後拒絕輸入的功能,請開顯示警告,你然你會發現,應該可以寫入的數值被莫名其妙的拒絕了,這一開始困擾我很久,還以為是我寫錯了,後來證實是他的bug...
  10. OnOpen function不執行的問題:所有script專案都會掛一個OnOpen的event,不過有時候他就是莫名其妙不會執行,答案是,你所有運算都要包在function裡面,不然就會造成這個錯誤,例如:
    
    var a = new Date();
    function OnOpen(){
        ...
    }
    

    這樣就會出錯了,建議解法是不要使用全域變數,或是自己再掛一個OnOpen的event上去就可以了
  11. 使用者資料讀取問題:剛剛提到google drive的權限控管很好用,他提供addEditor(emailAddress)、removeEditor(emailAddress)、getEmail()等function,讓你可以使用對方的email就可以快速刪改權限,爸特!,就是這個getEmail(),他有陷阱存在,他是去抓google plus的資料,所以如果對方沒有開放google plus的資料給人家看,那你就永遠抓不到他的email,會陷入可以用email加權限但是你不知道要怎樣砍他權限的問題...,解法是...乖乖開放你的email給朋友讀取吧....
  12. 讀取資料問題:一次讀取某個範圍的資料跟一次讀取一格資料所需的時間差不多,所以可以的話就一次讀出一堆資料再來處理,寫入也是一樣,反正記憶體不算在使用額度內 XD
綜合以上幾點,要用google apps script開發中小型軟體系統,最好考慮到未來擴充性的問題,因為每個帳號每天有扣打限制,所以要設計的有平行處理的功能,因為穩定性問題,要考慮接續上一次處理進度的問題,這樣才能避免程式運作不順利。

一次寫了這麼多好像都在抱怨google apps script的缺點 XD,不過這都是我開發過程中的心得,事實上,使用google apps script開發這個專案幫我省下了UI開發時間、權限控管問題,安全性問題,跨平台問題,資料同步問題,重要的是還不必有一台伺服器24小時運作。

希望大家開發google apps script順利 :)

2 則留言:

Sdany 提到...

您好,請教一個問題

我在寫 GmailApp 一直遇到瓶頸
我的信有數封,其中有的是回覆的
我使用 filter 時,取出主要的信
var threads = GmailApp.search(filter, 0, 5);
要加到一個 label 中,只能使用
threads[x].addLabel(label);
但是上面這個方式會把沒必要的信一起加進去(含回覆的信)
我希望能使用下面的語法
threads[x].getMessages()[y].addLabel(label);
確無此功能

我該如何把獨立的 Messages() 加到我指定的 label 呢?

我一直找不到解決方法,是否有辦法做到呢?

jikker 提到...

沒有用過gmail app
你要不要試試看先找出單一信件的id之類的
在使用addLabel這個method看看