入門教學 · 關西國小資訊組

GAS 是什麼?

Google Apps Script — 讓 Google 服務動起來的「劇本語言」

課前調查

你對 GAS 的了解程度如何?

😶
從沒聽過,那是什麼碗糕
👀
知道這個東西,但沒用過
🛠️
有使用過,曾經部署過網頁
🚀
很常使用,且部署過很多專案
📡 連接中…
總計 0 票
概念導入

什麼是腳本

📋

腳本 = 寫給電腦看的「指令清單」

在電腦的世界裡,「Script(腳本)」就是一套按順序寫好的指令,讓電腦依照步驟自動完成特定任務,不需要你每次手動操作。

🎬

GAS 的比喻

把 Google 服務想像成演員(Sheets、Gmail、Drive、表單),GAS 就是替他們寫好的劇本,告訴每個角色什麼時候、做什麼事。

登場角色

GAS 的演員陣容

📊
Google 試算表
資料庫 · 數據計算
📧
Gmail
自動寄信 · 回覆通知
📁
Google 雲端硬碟
檔案建立 · 資料夾管理
📝
Google 表單
收集資料 · 觸發動作
📅
Google 日曆
行程建立 · 提醒排程
💬
Google Chat / LINE
即時通知 · Bot 整合
✨ GAS 最強大的地方:讓這些服務「互相講話」
通知整合

Google ChatLINE Bot

💬
Google Chat
Google Workspace 內建通訊
✅ 透過 Webhook 網址傳送訊息
✅ 支援 Card 格式(按鈕、圖片、表格)
✅ 免費,學校 Google Workspace 直接用
✅ 可發送到指定 Space 或個人
→ 按 ↓ 看更多
🟢
LINE Bot
台灣最普及的通訊 App
✅ 透過 Messaging API 傳送訊息
✅ 支援 Flex Message(高度客製化)
✅ 可推播給個人或群組
✅ 家長、老師幾乎人人都有
→ 按 ↓ 看更多
⬇ 向下繼續
通知整合 · Google Chat

💬 Google Chat 如何使用?

Step 1 — 建立 Webhook
在 Google Chat Space → 管理 Webhook → 新增 → 複製網址
Step 2 — GAS 傳送訊息
const WEBHOOK = "https://chat.googleapis.com/v1/...";
UrlFetchApp.fetch(WEBHOOK, {
  method: 'post', contentType: 'application/json',
  payload: JSON.stringify({ text: "✅ 自動通知訊息!" })
});
Step 3 — Card 格式(進階)
用 JSON 建立卡片:標題、說明文字、圖片、按鈕,視覺效果更豐富
💡 應用情境:每天早上自動推播天氣、午餐菜單、課表提醒到學校群組
⬇ 繼續看 LINE Bot
通知整合 · LINE Bot

🟢 LINE Bot 如何使用?

Step 1 — 申請 LINE Messaging API
LINE Developers → 建立 Provider → 建立 Messaging API Channel → 取得 Channel Access Token
Step 2 — GAS 傳送訊息
const TOKEN = "你的 Channel Access Token";
UrlFetchApp.fetch("https://api.line.me/v2/bot/message/broadcast", {
  method: 'post',
  headers: { Authorization: 'Bearer ' + TOKEN, 'Content-Type': 'application/json' },
  payload: JSON.stringify({ messages: [{ type: 'text', text: '📢 全員通知!' }] })
});
Step 3 — Flex Message(進階)
用 JSON 客製化訊息外觀:圖片、按鈕、表格樣式,比純文字更吸睛
💡 應用情境:家長聯絡簿回條提醒、學生作業繳交通知、緊急停課公告
⬆ 向上返回 / ➡ 下一主題
核心功能

GAS 能做三件大事

🤖

A. 自動化重複的工作 (Automation)

每天早上 8 點自動讀取試算表業績數據,整理後寄 Email 給主管。你不用動手,Google 的伺服器幫你執行。

🔗

B. 連接不同的 Google 服務 (Integration)

有人填寫表單報名後,自動在日曆建立行程、在雲端硬碟建立專屬資料夾,一氣呵成。

🧩

C. 擴充原有功能 (Extension)

試算表沒有換匯公式?自己寫一個 =TWD2JPY(100) 當自定義函數直接用。

優點

為什麼 GAS 這麼受歡迎?

01

不用安裝任何軟體

有瀏覽器 + Google 帳號就能開始,打開網頁就能寫程式。

02

基於 JavaScript

世界最流行語言之一,學習資源豐富,做過網頁就有基礎。

03

完全免費

Google 提供的免費額度對個人、學校、中小企業都非常夠用。

04

雲端執行不怕關機

程式在 Google 伺服器跑,電腦關掉排程照樣準時執行。

系統架構

GAS 前端 / 後端 / 資料庫

🌐
前端
index.html
(使用者畫面)
⚙️
後端 (GAS)
Code.gs
doGet() 部署
📊
資料庫
Google Sheets
(免費儲存)
🔔
通知
LINE Bot
Google Chat
⚠️ 新增 HTML 檔案時不須加 .html 副檔名
doGet() 裡寫的名稱就是頁面入口,大小寫有差異要注意。
重點整理

開發前必知的5 件事

1
前端 = HTML 檔案,首頁通常命名為 index,由 doGet() 決定要顯示哪個頁面。
2
後端 = .gs 檔案,可用英文或中文命名,處理邏輯與資料。
3
Google Sheets = 資料庫,免費、簡單、直觀,是 GAS 的最佳搭檔。
4
LINE Bot / Google Chat讓系統有了即時通知的能力。
5
觸發條件(Trigger)讓程式自動排程執行,實現真正的無人化服務。
實用技巧

常用快捷鍵程式撰寫

⌨️ 常用鍵盤組合
Ctrl + A
全選
Ctrl + C
複製
Ctrl + V
貼上
Ctrl + F
尋找
Shift + Enter
強制換行
與 Gemini 對話換行用此,直接 Enter 會送出!
💻 程式撰寫
單行註解
// 這是單行註解
只能註解「該行」後面的內容
整段註解
/*
  可以跨越多行,整段都是註解
*/
/* 開頭、*/ 結尾
💡 註解的用途:說明程式的功能,或暫時關掉某段程式不讓它執行
名詞定義

常見的 ID 試算表讀取

🆔 常見的 ID
📊 Google Sheets ID
https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms/edit
/d/ 之後、/edit 之前那一串 = Sheets ID
📁 Google Drive 資料夾 ID
https://drive.google.com/drive/folders/1a2b3c4d5e6f7g8h9i
/folders/ 之後那一串 = 資料夾 ID
🖼️ 圖片 ID(需透過共用連結)
https://drive.google.com/file/d/1n-scmbz0zqbEFBJEo_qJ_IJT-V3uo3yo/view?usp=sharing
/d/ 與 /view 之間那一串 = 圖片 ID
📖 Google Sheets 四種讀取方式
① 指定試算表 + 指定工作表
const sheet = SpreadsheetApp
  .openById(SPREADSHEET_ID)
  .getSheetByName(SHEET_NAME);
② 當前試算表 + 當前工作表
var sheet = SpreadsheetApp
  .getActiveSpreadsheet()
  .getActiveSheet();
③ 指定試算表 + 當前工作表
const sheet = SpreadsheetApp
  .openById(SHEET_ID)
  .getActiveSheet();
④ 當前試算表 + 指定工作表
var sheet = SpreadsheetApp
  .getActiveSpreadsheet()
  .getSheetByName('工作表名稱');
Google Sheets 操作

📖 讀取試算表資料

① 讀取單一儲存格
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const val = sheet.getRange("A1").getValue();
Logger.log(val);
② 讀取整個範圍(二維陣列)
// 讀取 A1:C10 所有資料,回傳二維陣列
const data = sheet.getRange("A1:C10").getValues();
// 逐行處理
data.forEach(row => { Logger.log(`姓名: ${row[0]}, 分數: ${row[1]}`); });
③ 讀取到最後一行(動態範圍)
// 自動偵測資料有幾行,不用寫死範圍
const lastRow = sheet.getLastRow();
const data = sheet.getRange(1, 1, lastRow, 3).getValues();
// getRange(起始列, 起始欄, 總列數, 總欄數)
⬇ 繼續看寫入資料
Google Sheets 操作

✏️ 寫入試算表資料

寫入單一儲存格
// 在 B2 寫入文字
sheet.getRange("B2").setValue("Hello GAS!");
// 在 C3 寫入當前時間
sheet.getRange("C3").setValue(new Date());
在最後一行新增一筆資料
const lastRow = sheet.getLastRow();
// 在下一行寫入一列資料(陣列對應欄位)
sheet.getRange(lastRow + 1, 1, 1, 3).setValues([
  ["王小明", 95, new Date()]
]);
appendRow — 最簡單的新增方式 ⭐
// 直接在最後加一行,最簡潔!
sheet.appendRow(["王小明", 95, new Date()]);
⬇ 繼續看實用技巧
Google Sheets 操作

實用技巧與常見模式

清除儲存格內容
// 清除值但保留格式
sheet.getRange("A1:C10").clearContent();

// 全部清除(含格式)
sheet.getRange("A1:C10").clear();
搜尋特定值
const data = sheet.getDataRange().getValues();
const found = data.find(row => row[0] === "王小明");
Logger.log(found);
getDataRange — 自動抓全部資料
// 不用指定範圍,自動抓有資料的區域
const all = sheet.getDataRange().getValues();

// 跳過標題列(第一行)
const rows = all.slice(1);
💡 效能提醒
盡量用 getValues() 一次讀取,避免在迴圈裡重複呼叫 getValue(),會大幅拖慢速度!
⬆ 向上返回 / ➡ 下一主題

開始寫你的第一個腳本吧!

GAS 不需要伺服器、不需要費用、不需要安裝環境。只要一個 Google 帳號,就能讓學校的工作變得更聰明。

#自動化 #JavaScript #免費 #雲端執行 #學校資訊化

Vincent Wang ⚡ Powered By Claude

第一支程式

🎯 我們要做什麼?

📋 任務一:遮蔽姓名
原始資料:王小明
↓ GAS 處理
輸出結果:王○明
把姓名中間那個字替換成「○」,保護個資但仍可辨識
🔧 任務二:建立工具列
在 Google 試算表頂端選單新增一個「自訂工具列」,讓老師直接點選按鈕就能執行程式,不需要進 GAS 編輯器
📊 試算表範例結構
欄A 欄B 欄C
姓名(原始) 班級 遮蔽後姓名
王小明 三年一班 王○明
陳大中 三年二班 陳○中
李美華 三年三班 李○華
💡 A欄放原始姓名,C欄用GAS自動寫入遮蔽後的結果
⬇ 看程式碼
第一支程式

💻 完整程式碼

① 遮蔽姓名主函式
// 遮蔽 A 欄姓名,結果寫入 C 欄
function maskNames() {
 const sheet = SpreadsheetApp
  .getActiveSpreadsheet().getActiveSheet();
 const lastRow = sheet.getLastRow();
 const names = sheet
  .getRange(2, 1, lastRow-1, 1).getValues();

 const masked = names.map(row => {
  const name = row[0];
  if (name.length < 2) return [name];
  const result =
   name[0] + '○' + name.slice(2);
  return [result];
 });

 // 寫入 C 欄(從第2列起)
 sheet.getRange(2, 3, masked.length, 1)
  .setValues(masked);
 SpreadsheetApp.getUi().alert('✅ 完成!');
}
② 建立自訂工具列
// 開啟試算表時自動建立選單
function onOpen() {
 SpreadsheetApp.getUi()
  .createMenu('🔧 我的工具')
  .addItem('遮蔽姓名中間字', 'maskNames')
  .addToUi();
}
③ 重點說明
name[0] 取第1個字(姓)
name.slice(2) 取第3字之後(名)
onOpen() 開檔時自動執行的觸發器
createMenu() 在選單列新增自訂按鈕
⬆ 向上返回 / ➡ 下一主題