完整繁體中文版

Google Apps Script
表單整合完整指南

從網站前端送出聯絡表單、reCAPTCHA Token 與選用的 Base64 圖片,透過 HTTP POST 傳送至 Google Apps Script Web App,並完成驗證、圖片上傳、試算表寫入、Email 通知與錯誤紀錄。

3 種 POST 內容格式
5 MB 預設圖片上限
19 章 完整建置內容
Asia/Taipei 預設時區

1端到端流程

適用情境:網站將聯絡表單、reCAPTCHA Token 與選用的 Base64 圖片,透過 HTTP POST 傳送至 Google Apps Script Web App。

接收資料

支援 URL encoded、multipart 與 JSON。

安全驗證

驗證 reCAPTCHA、欄位與圖片。

儲存資料

圖片進 Drive,文字進 Sheets。

通知與紀錄

寄送 Email,錯誤寫入 LOG。

  1. 接收 application/x-www-form-urlencodedmultipart/form-dataapplication/json
  2. 驗證 Google reCAPTCHA。
  3. 驗證姓名、電話、Email、訊息與圖片。
  4. 將 Base64 圖片存入指定 Google Drive 資料夾。
  5. 將表單資料寫入 Google Sheets。
  6. 寄送 HTML Email 與圖片附件給管理員。
  7. 把圖片、Email 與主流程錯誤寫入 LOG 工作表。
  8. 回傳一致的 JSON 結果給前端。

2建議的 Apps Script 檔案結構

              Code.gs DriveAuthorization.gs appsscript.json
            
  • Code.gs:完整的請求處理、驗證、儲存、通知與錯誤紀錄。
  • DriveAuthorization.gs:手動觸發 Drive OAuth 授權並測試資料夾存取。
  • appsscript.json:選用的 Manifest,可明確宣告 OAuth Scopes。

3完整最佳化程式:Code.gs

將下列程式完整貼到 Code.gs。程式識別字與 Google API 名稱保留英文,以確保可直接執行;說明與註解採繁體中文。

正式上線前:請替換所有包含 REPLACE WITH 的設定值,並將 reCAPTCHA Secret 儲存在 Script Properties,而不是硬寫在原始碼。
展開/收合完整 Code.gs
                
              

4Drive 授權與存取測試:DriveAuthorization.gs

可手動執行的函式名稱不要加尾端底線,這樣才容易在 Apps Script 編輯器上方的函式選單中出現。

展開完整 DriveAuthorization.gs
                
              

5必要設定

至少必須更新下列設定:

              SPREADSHEET_ID: "實際的 Google Spreadsheet ID", FOLDER_ID: "實際的 Google Drive 資料夾 ID", SHEET_NAME: "Sheet1", ADMIN_EMAIL: "實際的管理員 Email"
            

Spreadsheet ID

網址範例:https://docs.google.com/spreadsheets/d/1AbCdEf123456/edit
其中 ID 為:1AbCdEf123456

Folder ID

網址範例:https://drive.google.com/drive/folders/1XyZ987654
其中 ID 為:1XyZ987654

6設定 reCAPTCHA Secret

不要把 Secret Key 寫死在原始碼。若 Secret 曾出現在公開訊息、Repository、截圖或共享文件,請撤銷並重新產生。

在 Apps Script 中依序進入:

              專案設定 → 指令碼屬性(Script Properties) → 新增指令碼屬性
            
屬性
RECAPTCHA_SECRET 實際的 reCAPTCHA Secret Key

7Google Sheets 欄位順序

內容
A 送出時間
B 姓名
C 電話
D Email
E 訊息
F 圖片連結

LOG 工作表不存在時會自動建立。

8觸發 Google Drive 授權

  1. authorizeDriveAccess 貼到 DriveAuthorization.gs
  2. 設定實際的 TEST_FOLDER_ID
  3. 儲存專案。
  4. 在 Apps Script 編輯器上方函式選單選擇 authorizeDriveAccess
  5. 按下「執行」。
  6. 完成 Google OAuth 授權流程。
  7. 確認測試文字檔已出現在目標 Drive 資料夾。
不要手動執行 doPost。它需要 Web App 傳入事件物件 e

9若 authorizeDriveAccess 沒有出現在函式選單

  • 函式名稱尾端不能有底線。
  • 函式必須宣告在最外層。
  • 專案必須先儲存。
  • 任何 .gs 檔案都不能有語法錯誤。
  • 重新載入 Apps Script 編輯器。
              // 正確:可手動執行 function authorizeDriveAccess() {}  // 不建議作為手動入口 function authorizeDriveAccess_() {}  // 內部輔助函式可使用尾端底線 function parseDataUrl_() {}
            

10Google Drive 資料夾共享權限

OAuth 授權與資料夾共享是兩件不同的事。部署 Web App 的帳號必須:

  • 擁有該資料夾,或被明確加入該資料夾。
  • 具備新增或編輯檔案的權限。
當 Web App 設定為「以我的身分執行」時,「我」指的是部署該 Web App 的帳號。

11Web App 部署

              部署類型:網頁應用程式(Web app) 執行身分:我(Me) 誰可以存取:依網站需求選擇
            

使用「以我的身分執行」時:

  • Drive 使用部署者權限。
  • Spreadsheet 使用部署者權限。
  • MailApp 使用部署者寄信配額。
  • 網站訪客不需要擁有 Drive 資料夾權限。

更新程式後重新部署

              部署 → 管理部署作業 → 編輯 → 選擇新版本 → 部署
            

正式網站請使用 /exec 網址。

12選用 appsscript.json

多數情況 Apps Script 會自動推斷需要的權限。若要明確宣告 OAuth Scopes,可使用:

              {"timeZone":"Asia/Taipei","exceptionLogging":"STACKDRIVER","runtimeVersion":"V8","oauthScopes":["https://www.googleapis.com/auth/drive","https://www.googleapis.com/auth/spreadsheets","https://www.googleapis.com/auth/script.send_mail","https://www.googleapis.com/auth/script.external_request"]}
            

變更 Scopes 後通常需要重新授權。

13前端送出範例

FormData

              
            

JSON

              
            
前端應同時檢查 result.okresult.statusCode,不要只依賴 HTTP Status Code。

14回應格式

成功

              {"ok":true,"statusCode":200,"requestId":"唯一識別碼","mailSent":true,"imageSaved":true,"fileUrl":"Google Drive 檔案網址"}
            

失敗

              {"ok":false,"statusCode":500,"requestId":"唯一識別碼","error":"錯誤說明"}
            

正式環境建議:RETURN_DEBUG_INFO: false

15圖片資料格式

完整 Data URL

              data:image/png;base64,iVBORw0KGgoAAA...
            

原始 Base64

              iVBORw0KGgoAAA...
            

傳送原始 Base64 時,請另外提供:

              image_mime=image/png
            

允許格式:PNG、JPEG、JPG、WebP、GIF。預設上限為 5 MB

16安全性檢查清單

  • reCAPTCHA Secret 只放在 Script Properties。
  • 正式環境關閉 Debug 回應。
  • 限制圖片 MIME 類型與檔案大小。
  • 不要信任前端傳入的 summary_html
  • 使用 escapeHtml_() 防止 Email HTML Injection。
  • 使用 safeSheetText_() 防止試算表公式注入。
  • 不要把完整 Token 或 Base64 圖片寫入 Log。
  • 正式環境預設保持 MAKE_FILE_PUBLIC: false
  • 任何曾曝光的 Secret 都必須撤銷並重新產生。

17常見錯誤與排除方式

Access denied: DriveApp

可能原因:尚未完成 OAuth、登入錯誤帳號、Workspace 管理員封鎖 Drive、權限被撤銷,或 Manifest 缺少 Drive Scope。

  1. 執行 authorizeDriveAccess
  2. 使用部署帳號完成授權。
  3. 確認 Folder ID。
  4. 確認資料夾共享權限。
找不到資料夾

只傳入資料夾 ID,不要傳完整網址。

                DriveApp.getFolderById("FOLDER_ID_ONLY");
              
編輯器測試成功,但 doPost 失敗
  • 確認 Web App 已更新為新版本。
  • 確認網站使用最新 /exec 網址。
  • 確認 Web App 以正確帳號執行。
  • 確認部署帳號可存取 Sheet 與 Drive。
  • 查看 Apps Script「執行作業」頁面與 LOG 工作表。
其他人無法開啟圖片連結

這是 Drive 分享權限問題,不是 OAuth 問題。可設定 MAKE_FILE_PUBLIC: true,但 Workspace 政策仍可能封鎖公開分享。

reCAPTCHA action 不一致
                // 前端 grecaptcha.execute(siteKey, { action: "submit" });  // 後端 RECAPTCHA_EXPECTED_ACTION: "submit"
              

前後端值必須完全相同。

18完成檢查表

  • Spreadsheet ID 已替換。
  • Folder ID 已替換。
  • Sheet 名稱正確。
  • 管理員 Email 正確。
  • Script Properties 已建立 RECAPTCHA_SECRET
  • 已手動執行 authorizeDriveAccess
  • Drive 測試檔案已建立。
  • 部署帳號可編輯 Drive 資料夾。
  • 試算表欄位順序正確。
  • 已部署新的 Web App 版本。
  • 正式網站使用 /exec 網址。
  • 正式環境 RETURN_DEBUG_INFO 為 false。
  • 已完成一次真實的前端送出測試。
  • 已確認 Sheets、Drive、Email、LOG 與 Executions。

19建議設定順序

  1. 建立 Google Drive 目標資料夾。
  2. 建立 Google Spreadsheet。
  3. 新增工作表標題列。
  4. 把資料夾分享給 GAS 部署帳號。
  5. 貼上完整程式。
  6. 完成 CONFIG 設定。
  7. 把 reCAPTCHA Secret 加入 Script Properties。
  8. 執行 authorizeDriveAccess
  9. 執行 authorizeRequiredServices
  10. 部署為 Web App。
  11. /exec 網址放到前端。
  12. 送出測試表單。
  13. 確認 Sheets、Drive、Email、LOG 與 Executions。
完成標準:前端收到 ok: true,資料成功寫入 Sheets,圖片出現在 Drive,管理員收到 Email,且 LOG 與執行紀錄無未處理錯誤。