2014年12月7日 星期日

(終極版)用Google Sheet做出報名、連署、抽獎完整解決方案

晚上11:17 Posted by Envisioning U-Commerce Lab
這篇文章(尚未完成)大部分介紹程式開發過程中循序漸進寫出來的九個版本,然後在課堂上逐一解說程式設計重點。


在開始介紹此程式開發歷程之前,應有認知:  Google Apps Script: 3.3B weekly executions; 8.7M weekly end users; and 270K weekly developers.Container-bound Scripts v.s. Standalone Scripts




首先,參考第一版Google Sheet「報名 (v.1 GAS 執行 display Sidebar for Announce Checklist)」建立副本,由於原來的Google Sheet是已經有一個連動的Google Form(如下圖的[報到]工作表名稱前有紫色圖示),所以建立副本也應該有產生出兩個檔案(至雲端硬碟查看)




這個版本重點是參考在Sidebar置入表單範例在Sidebar置入HTML語法,呈現表單讓使用者決定挑選哪些欄位要複製到[名單公開(部分個資)]工作表,表單填好送出就會依sendForm設定去執行confirming2Clone函式,而其callback設定會回到ready執行google.script.host.close()側邊欄關閉(程式語法和邏輯會在課堂上說明,而且在程式碼裡面也有語法範例參考網址。)




這個showSidebar4announce函式的執行是綁定在Spreadsheet自訂選單(如下圖的[自訂功能]選單就是用Script程式產生出來的,有關addMenu自訂選單並將其寫在onOpen函式的介紹就不再贅述。)


第一次會跳出對話框要求授權,當然後續每一步都要同意允許(就省略擷取畫面囉)


出現側邊欄讓使用者決定挑選哪些欄位要複製到[名單公開(部分個資)]工作表


等到函式執行完畢,查看 > 記錄,就可看到傳入confirming2Clone函式的陣列資料,確認是符合選擇的結果








接著,用第二版Google Sheet「報名 (v.2 GAS 加上 Announce Checklist Confirming2Clone)」建立副本,這個版本重點放在confirming2Clone函式,準備利用儲存格B1,"特定記錄"後面加上記錄有哪些欄位被設定至名單公開。













再來要處理觸發條件設定,新資料存進[表單回應]工作表,程式就會自動將指定欄位複製到[名單公開(部分個資)]工作表,這部分放在第三版Google Sheet「報名 (v.3 GAS 加上 TriggerBuilder for Confirming2Clone)」用它來建立副本吧Script程式重點是在addFormSubmissionListener函式,newTrigger對於forSpreadsheet設定onFormSubmit表單資料進來時就觸發submissionCloning函式執行複製程序,也就是把[表單回應]工作表要複製的那些欄位放進二維陣列,再將二維陣列資料寫到[名單公開(部分個資)]工作表











下個步驟,讓使用者設定自動回覆確認信啟用/停用,這部分放在第四版Google Sheet「報名 (v.4 GAS 加上 display Sidebar for Auto-Reply setting)」用它來建立副本吧Script程式重點是在Sidebar置入HTML語法,呈現表單讓使用者決定是否啟動自動回覆確認信,並指定哪個是要求填寫信箱之欄位。而為了有更充分的訊息讓使用者知道,在showSidebar4autoreply函式兜出sheet發佈後的網址getRemainingDailyQuota得知當日發送郵件餘額(以Script程式發送郵件數量是有限制的,每日額度一般Gmail是100人次、G Suite教育版則是1500人次),並以getConfirmationMessage取得目前設定的表單提交後的訊息













為了產生自動回覆確認信,就必須再寫個寄發郵件的函式,這部分放在第五版Google Sheet「報名 (v.5 GAS 加上 after confirming for Auto-Reply setting)」用它來建立副本吧。Script程式重點是在confirming2Reply函式利用儲存格B1,"特定記錄"後面加上最後兩格記錄@自動回覆信箱欄位。至於自動回覆確認信,是在sendmail2user函式組成MailApp.sendEmail的htmlBody,就能寄發郵件了。








不過,兜出sheet發佈後的網址並非是由Script自動設定發佈喔,因為Script裡面沒有很容易的方式可以讓程式去執行這樣的設定,所以還是要由使用者手動設定,請執行: 檔案 > 發佈到網路 > 從整份文件下拉選單中選擇 [名單公開(部分個資)] 再按下發佈。











如果要讓自動回覆確認信裡面包含填答者在提交後可以編輯的網址,有不少細節需要處理,這部分放在第六版Google Sheet「報名 (v.6 GAS 加上 getEditResponseUrl for Auto-Reply Mail)」用它來建立副本吧。首先,在showSidebar4autoreply函式的側邊欄內容,可勾選確認信內容是否加入可編輯該筆回應的表單網址。


然後,在confirming2Reply函式判讀儲存格B1,"特定記錄"後面加上最後兩格記錄@自動回覆信箱欄位,大小寫字母分別代表設定信件內容是否加入可進行編輯的網址


最後,在submissionCloning函式增加參數e,這個參數非常關鍵,如果從e取得的datetime與工作表1最後一筆的timestamp相差無幾(1秒內,即1000毫秒),應是新填的表單回應,而對於新填或再編輯的表單回應會有不同的處理細節
















既然已經將[名單公開(部分個資)]工作表發佈到網路了,那也可以考慮寫在表單說明讓填表者注意到這項資訊,這部分放在第七版Google Sheet「報名 (v.7 GAS 加上 set Description to the linked Form)」用它來建立副本吧Script程式重點是在csetDescription2form函式,以setDescription將文字寫入表單說明中。














暫時來到目前最後一個版本,要處理的設定表單接受回應截止日期時間,這部分放在第八版Google Sheet「報名 (v.8 GAS 加上 TriggerBuilder for Responses Accept)」,用它來建立副本。Script程式重點是newTrigger對於forSpreadsheet設定timeBased時間觸發stopAcceptingResponses函式執行setAcceptingResponses關閉表單接受回應。另外也做了檢查,若重複執行就要刪除先前設定的觸發條件









這部分的後續發展(尚未完成)將會是:
  •  哪些欄位要複製到[名單公開(部分個資)]工作表之後要進行 "去識別化" 處理
  • 基於個資保護考量,每日觸發寄信給管理者告知這些資料還在雲端上的存取權限狀態,尤其是停止公告後還在雲端上卻未將存取權限關閉要特別警示。












完成前述版本之後,我們又再加了一個彩蛋功能,提供一個很炫的抽獎程式,這部分放在第X版Google Sheet「報名 (v.X GAS 加上 deploy Lucky Draw Script as Web App)」,用它來建立副本。原本程式雖然是Container-bound Script,但也可以 發佈 > 部署為網路應用程式 成為Web APP,也就多了一個抽獎網頁程式這個程式是從這個原始碼(在线演示)寫而成的,執行抽出得獎者的過程中隨機動態跳出姓名並等待按鈕決定停跳而抽出得獎者。



前述抽獎網頁程式改寫成Google Apps Script,讓它可執行前必須有幾個程序要先做。第一步驟,在[得獎公告]工作表G1儲存格的公式 =JOIN(";",ARRAYFORMULA(CONCAT(FILTER('表單回應'!D2:D, NOT(ISBLANK('表單回應'!D2:D))), "("&FILTER('表單回應'!C2:C, NOT(ISBLANK('表單回應'!C2:C)))&")"))) ,在此標示藍底的D應視[表單回應]工作表中的哪一題是姓名欄位而定,第一題就是D、是第二題就要改成E、是第三題就要改成F、......。


其實G1儲存格的公式並不算太複雜,原則上就是用CONCAT連接姓名、序號兩個欄位值,但必須先用FILTER檢查兩個欄位值都不可為空(也就只到有資料的最後一列),然後用ARRAYFORMULA將多列的資料都一次處理完,最後讓JOIN使用指定分隔符號(;)將陣列資料串聯在一起而成為完整名單字串。


第二步驟,在[得獎公告]工作表B、C欄自行輸入獎項名稱及數量,抽獎網頁程式的執行則是每抽完一個獎項就依序寫入第2,3,4...列的D,E,F欄,也就能與你自行輸入的獎項名稱對應上。




第三步驟,發佈為Web APP的設定沒辦法以程式做到,所以就只能自己手動設定囉,先在Spreadsheet執行 工具 > 指令碼編輯器。



在指令碼編輯器視窗開啟之後(什麼都不要亂動喔,切記! 切記! ),就只要執行 發佈 > 部署為網路應用程式,這裡要做的設定必須是 [專案版本 : 新增]、[將應用程式執行為 : 我]、[具有應用程式存取權的使用者 : 任何人,甚至是匿名使用者],再按下部署,最後就能得到該網頁程式的網址。




開啟該網址,出現如下畫面就代表已成功發佈為Web APP




第四步驟,要有資料才能測試執行抽獎網頁程式,臨時在[表單回應]工作表中輸入幾筆序號及姓名(若你手邊沒有資料可測試就複製這個Sheet裡面的部分資料吧)


再到[得獎公告]工作表中查看G1儲存格,應該可以看到這裡的公式自動將所有姓名序號組合成名單字串,以備抽獎網頁程式之用。


抽獎網頁程式會讀取名單進來,下方的開始按鈕也就會出現名單總人數,此時程式已準備就緒。


那就輸入這次要抽出的人數(舉例輸入5,單次最多抽49人喔),然後按下開始就進行抽獎囉,此過程會隨機在畫面中間不斷呈現人名,直到按下停止鈕。


按下停止之後,這次抽出的人名就會呈現在畫面上。(這些已抽出的名單將不會進入下一輪的抽獎資格)


回到[得獎公告]工作表來看,這次抽出的時間戳記、人數、名單都會記錄起來。


繼續再抽下一個獎項,輸入人數(舉例輸入3)再次按下開始進行抽獎,直到按下停止之後,抽出的人名呈現在畫面上。


回到[得獎公告]工作表來看,再次抽出的時間戳記、人數、名單果然依序記錄。




第五步驟,完成測試抽獎網頁程式之後,了解其執行及使用方式,就可以放心用這個程式進行正式抽獎。在正式抽獎之前,記得按右下角的重置鈕,讓先前的測試記錄都加以清除。






在公開抽獎之後,若要將抽獎結果公告在網路上,就要將[得獎公告]工作表發佈到網路,然後將發佈後的網址予以公告。