## 1. 認識 Google Apps Script
Google Apps Script 是一種程式碼語言,語法類似 Javascript,開發者完全不需要準備開發工具,就可以擴展 Google Apps 建構類似巨集的效果,達到工作流程自動化的目標,也可以建立 Web 應用程式,整合 Google 協作工具。
## 2. 為什麼要使用 Google Apps Script
Google Apps Script (GAS) 的核心價值在於**「自動化」與「整合」**。
它就像是 Google Workspace (Gmail, Sheets, Docs, Drive 等) 之間的強力膠水,可以把不同的服務串接起來,為你省去大量重複性的手動作業。
## 3. GAS 啟動方式
([https://script.google.com/](https://script.google.com/))
第一個範例 :
```javascript
Logger.log("Hello World");
```
## 4. GAS 常見應用
**(1). Google Sheets (試算表) 自動化**
這是 GAS 最廣泛應用的領域,可以讓試算表變身為強大的資料庫或應用程式。
* **自動化報表與通知:** 每天早上自動整理前一天的銷售數據,並將摘要透過 Email 或通訊軟體寄給主管。
* **資料清理與格式化:** 一鍵刪除重複項、修正日期格式、或根據條件自動將整列資料移動到另一個分頁。
**(2). Gmail 與通訊整合**
* **客製化大量寄信 (Mail Merge):** 讀取 Google Sheets 裡的客戶名單(姓名、Email、專屬內容),自動發送數百封內容各自不同的客製化信件(類似 Word 合併列印)。
* **自動儲存附件:** 監控收件匣,自動將特定標籤(如「發票」、「報表」)的郵件附件下載並轉存到 Google Drive 指定資料夾。
**(3). Google Forms (表單) 進階應用**
讓表單不只是收集資料,還能觸發後續流程。
* **自動回覆系統:** 使用者填寫表單後,系統自動寄出一封包含其填寫內容確認或 PDF 憑證的 Email。
* **簽核流程自動化:** 員工填寫請假單後,系統自動寄信給主管審核;主管點擊信中連結(核准/駁回)後,系統自動更新試算表狀態並通知員工。
**(4). Google Docs 與 Drive (文件與檔案管理)**
* **自動生成文件:** 根據 Sheets 裡的訂單資料,自動套用 Google Docs 範本,生成精美的 PDF 報價單、發票或合約,並存入 Drive。
**(5). Web App (網頁應用程式)**
GAS 可以被部署為簡單的網頁應用程式 (Web App)。
* **簡易後台系統:** 建立一個簡單的 HTML 網頁介面讓員工輸入資料,資料直接寫入 Google Sheets,避免讓員工直接接觸到底層的試算表數據,保護資料安全。
* **API Endpoint:** 將 GAS 寫成一個簡易的 API 接口,讓其他程式或網站可以傳送資料進來 Google Sheets。
---
## 4. 使用 Vibe Coding 開發 GAS
使用 clasp (Apps Script CLI), 可讓您在自己的電腦上編寫程式碼,並在完成後上傳到 Apps Script。
### 案例 1 使用 vibe coding 建立一個獨立的 GAS
```javascript
**步驟 1:** 這是一個 GAS 的專案目錄,請幫我建立 clasp 環境
**步驟 2:** 我要新增一個名為 `normalizeErrorType` 的函式。
邏輯需求:
(1). 輸入參數為 `inputString`。
(2). 使用 switch 或 if-else 邏輯進行分類:
* 如果字串包含 "馬達" 或 "Motor" (不分大小寫),回傳 "ERR_MOTOR"。
* 如果字串包含 "過熱" 或 "Overheat",回傳 "ERR_OVERHEAT"。
* 其他情況回傳 "ERR_UNKNOWN"。
```
### 案例 2 使用 vibe coding 建立試算表中可應用的 GAS
```javascript
**步驟 1:**
新增一個 `onEdit(e)` 觸發函式。
實作邏輯:
(1). 取得巡檢表物件, ID 為 {}。
(2). 檢查工作表 1 是否為第 3 欄 (Column C)。
(3). 如果輸入的數值大於 100:
* 使用 `e.range.setValue(oldValue)` 將值復原 (或是設為空)。
* 使用 `Browser.msgBox` 跳出警告視窗:「數值不能超過 100」。
```
### 案例 3 使用 vibe coding 建立表單系統
```javascript
**步驟 1:**
請你幫我做一個 google form, 我要點飲料
我的前端要用 index.html
GAS, clasp 進行佈署
**步驟 2:**
幫我佈署
**步驟 3:**
在 GAS 上佈署讓 index.html 可以直接顯示
**步驟 4:**
在 "五桐號訂飲料紀錄" 的 google sheet 中新增標籤頁統計各種飲料的杯數
```
### 案例 4 使用 vibe coding 建立發送電子信系統
```javascript
**步驟 1:**
請你幫我做一個 google sheets, 我要整理客戶名單,相關欄位包括 "客戶名稱"、"客戶電話"、"客戶 EMAIL"
前端做一個 index.html,滿足以下條件:
1. 讀取客戶名單中的所有客戶並用表格的方式呈現
2. 每個客戶都可以透過核取方塊選取
3. 畫面下方有一個 "寄信通知" 按鈕,按下後自動依照客戶名單中的 "客戶 EMAIL" 發送電子信
4. 電子信主題: 10/10 優惠活動通知 電子信內容: 10/10 店內所有產品滿千送百
5. 電子信發送完成後,自動重新讀取客戶名單,僅讓沒發送過的客戶出現
clasp 進行佈署
**步驟 2:**
幫我佈署
```
---
### 終極案例 「工單/異常回報自動分派」
**目標:** 現場填單→自動帶出產線/設備→依規則分派給維修/製程→寄信通知→進度更新回寫
#### 系統拆解:
**第一階段:系統架構與 IPO 總覽**
這個 Web App 的核心架構通常是:
* 前端 (Client): HTML/CSS/JS (使用者介面)
* 後端 (Server): Google Apps Script (GAS)
* 資料庫 (Database): Google Sheets
**第二階段:詳細 IPO 拆解**
我們依據流程 "填單 → 帶出資料 → 規則分派 → 寄信 → 回寫" 來進行細部拆解:
**1. Input (輸入層) - 介面與資料獲取**
這部分關注「使用者給系統什麼」以及「系統需要什麼預設資料」。
* **使用者輸入 (User Inputs):**
* 基礎資訊: 填單人工號/姓名、發生時間 (可自動抓取)。
* 關鍵參數: 產線區域 (Dropdown)、設備編號 (連動選單)、異常狀況描述、照片上傳 (選用)。
* 觸發條件: 選擇「異常類型」 (例如:機械故障、參數異常),這將作為後續分派的依據。
* **預設資料輸入 (Master Data Inputs):**
* 產線/設備對照表: 預先存在 Google Sheet 的清單,讓前端呼叫。
* 人員名單與 Email: 維修人員與製程工程師的對應 Email 清單。
**2. Process (處理層) - GAS 核心邏輯**
這部分是系統的「黑盒子」,也是 GAS 發揮最大作用的地方。
* **P1: 動態資料處理 (前端互動邏輯)**
* 動作: 當使用者選擇「產線 A」時。
* 邏輯: GAS 讀取 Sheet 中的設備清單,篩選出屬於「產線 A」的設備,回傳給前端更新下拉選單 (避免手輸入錯誤)。
* **P2: 規則分派引擎 (核心演算法)**
* 邏輯判斷:
* IF 異常類型 == "機械/電控" THEN 分派給 "維修部"。
* IF 異常類型 == "配方/品質" THEN 分派給 "製程部"。
* 狀態設定: 將工單狀態預設為「待處理 (Open)」。
* ID 生成: 自動產生唯一的工單編號 (例如:T20251027-001)。
* **P3: 資料寫入 (資料庫操作)**
* 動作: 呼叫 SheetApp,鎖定最後一行 (getLastRow),將整理好的資料寫入 Google Sheet 的「工單紀錄表」。
**3. Output (輸出層) - 通知與回饋**
這部分關注「系統產出什麼結果」。
* **O1: 資料庫紀錄 (Database Record)**
* Google Sheet 中新增的一筆完整資料列 (包含時間戳記)。
* **O2: 自動化通知 (Notification)**
* 動作: 使用 MailApp.sendEmail 或 GmailApp。
* 內容: 根據 P2 的分派結果,寄送包含「工單連結、設備位置、問題描述」的信件給對應群組 (維修或製程)。
* **O3: 前端回饋 (User Feedback)**
* Web App 畫面顯示「報修成功!單號:xxx」,並重置表單。
**第三階段:進度更新回寫 (The Loop)**
你提到的最後一步「進度更新回寫」,其實是第二個 IPO 循環,通常透過 Email 中的連結或後台管理介面觸發:
* Input: 維修人員點擊信中連結,開啟「結案表單」,填寫「處理對策」與「完成時間」。
* Process: GAS 根據工單 ID 搜尋 Sheet 中的對應列,更新「狀態」欄位為「已完成 (Closed)」,並填入處理內容。
* Output: 寄發「完修通知」給原填單人,或更新 Dashboard 上的進度燈號。
#### 實作:
```javascript
**index.html 有兩個標籤頁可供切換**
**第一個標籤頁為填寫表單,表單中的內容包含以下欄位:**
1. **填單人工號/姓名** (`input type="text"`, required)
2. **產線區域** (`select`, id="lineSelect", required):
* 預設選項為 "Loading...",頁面載入時需自動呼叫後端 `getLineList()` 取得清單。
3. **設備名稱** (`select`, id="equipSelect", required):
* 預設狀態為 `disabled`。
* 當「產線區域」變更時,觸發 JS 呼叫後端 `getEquipList(selectedLine)`,並動態更新此選單。
4. **異常類型** (`select`, required):
* 選項包含:機械故障、電控異常、製程參數、品質異常、其他。
5. **異常描述** (`textarea`, rows="3")
6. **現場照片** (`input type="file"`, accept="image/*"):
* 支援手機拍照或上傳圖片。
**# 請實作以下邏輯:**
1. **初始化 (Initialization):**
2. **連動選單 (Cascading Dropdown):** - 當使用者選擇產線後,先清空設備選單,顯示 "Loading...",並解除 `disabled` 狀態,接著呼叫後端取得該產線的設備清單。
3. **表單提交 (Form Submission):**
* 攔截 `form.onsubmit` 事件,防止預設跳頁。
* **圖片處理 (關鍵):** 因為 GAS 無法直接傳送 Multipart Form,請使用 `FileReader` 將上傳的圖片轉為 **Base64 String**。
* 建立一個 JavaScript Object 包含所有欄位資料(含 Base64 圖片字串)。
* IF 異常類型 == "機械/電控" THEN 分派給 "維修部"並發送gmail ; 郵件標題:異常報修 內容:工單連結、設備位置、問題描述。
* IF 異常類型 == "配方/品質" THEN 分派給 "製程部"並發送gmail ; 郵件標題:異常報修 內容:工單連結、設備位置、問題描述。
* 狀態設定: 將工單狀態預設為「待處理 (Open)」。
* ID 生成: 自動產生唯一的工單編號 (例如:T20251027-001)。
4. **UX 回饋:**
* 送出表單時,按鈕要變更為 "傳送中..." 並 `disabled` 以防重複點擊。
* 成功後顯示 SweetAlert 或簡單的 alert 提示 "報修成功",並重置表單。
5. 收信者點擊信中連結,開啟「結案表單」,填寫「處理對策」與「完成時間」。
* GAS 根據工單 ID 搜尋 Sheet 中的對應列,更新「狀態」欄位為「已完成 (Closed)」,並填入處理內容。
**第二個標籤頁為管理資料庫,裡面有兩個功能:**
1. 建立 google sheet,並依照以下定義建立三個 sheet
> **"表單紀錄"包含欄位:**
> "工單編號 (ID)"
> "填單時間 (Timestamp)"
> "填單人 (Requester)"
> "產線區域 (Line)"
> "設備名稱 (Equipment)"
> "異常類型 (Issue_Type)"
> "異常描述 (Description)"
> "照片連結 (Photo_URL)"
> "分派部門 (Assigned_Dept)"
> "目前狀態 (Status)"
> "處理對策 (Solution)"
> "處理人員 (Handler)"
> "結案時間 (Close_Time)"
> **"設備清單(Master_Equip)"包含欄位:**
> "產線區域 (Line)"
> "設備名稱 (Equip_Name)"
> "設備編號 (Equip_ID)"
> "設備負責人 (Owner)"
> **"人員名單(Master_User)"包含欄位:**
> "部門 (Department)"
> "姓名 (Name)"
> "Email"
> "職責 (Role)"
> "負責異常類型 (Tag)"
2. 開啟這個 google sheet
GAS, clasp 進行佈署
```