Google apps script
2025 寒訓 - 吳綵芹 點點
GAS 編輯器操作
就是一些 起手式
開啟編輯器
< 方法一 > 從 Google Drive 開啟,開啟一個獨立的專案
- 進入 Google Drive (雲端硬碟)點選左上角新增
-
選擇 "更多" -> "Google Apps Script"

開啟編輯器
< 方法二 > 從已經存在的 Google 文件開啟,此為試算表示範。
- 建立 Google Sheets (試算表)
- 選擇左上角 "擴充功能" -> "Apps Script"

編輯器介面
各種功能簡單介紹一下

預設函式
選擇函式
添加檔案
其他差不多就是顧名思義
存檔
程式語言第一步!
GAS 操作
Hello World!
Logger.log('Hello World') ;
// 語法後面教
// 一樣記得字串引號
// 結尾分號
GAS 操作

存檔執行

成功長這樣
GAS 操作
然後就 成功了
Hello World!


javascript 基礎語法
Google Apps Script 語法以 JavaScript 為基礎。了解基礎 JavaScript 語法可以更快速學習 GAS 語法。
Index
變數賦值
變數 & 資料型別
var a = 0 ; // 一般變數
let b = 3 ; // 區塊變數
const c = 4 ; // 常數
let number = 42; // 數字
let string = "文字"; // 字串
let boolean = true; // 布林值
let date = new Date(); // 日期
let array = [1, 2, 3]; // 陣列
let object = {name: "John"}; // 物件
let null = null; // 空值
let undefined; // 未定義
資料類型
陣列建立、存取、元素操作
陣列
let arr = [1, 2, 3] ;
// Logger.log() 為 GAS 語法
Logger.log(arr) ; // [1.0, 2.0, 3.0]
Logger.log(arr[0]) ; // 1.0
arr.push(4) ; // 添加元素到陣列末
arr.unshift(0) ; // 添加元素到陣列前端
let last = arr.pop(); // 將末位元素儲存在變數 last 中,並從陣列移除
let first = arr.shift(); // 將第一個元素儲存在變數 first 中,並從陣列移除
let arr = [1, 2, 3, 4] ;
let double = arr.map(item => item * 2) ; // [2, 4, 6, 8]
let even = arr.filter(item => item % 2 === 0) ; // 條件判斷
arr.forEach(item => Logger.log(item)) ; // 逐一輸出
陣列操作
字串建立、操作
字串
let str1 = 'Hello' ;
let str2 = 'World' ;
let result = str1 + ' ' + str2 ; // Hello World
let template = `${str1} ${str2}!` ; // Hello World
let text = " Hello World ";
Logger.log(text.trim()); // "Hello World"
Logger.log(text.toLowerCase()); // " hello world "
Logger.log(text.toUpperCase()); // " HELLO WORLD "
Logger.log(text.split(" ")); // ["", "", "Hello", "World", "", ""]
Logger.log(text.replace("World", "GAS")); // " Hello GAS "
Logger.log(text.includes("World")); // true
Logger.log(text.substring(2, 7)); // "Hello"
物件建立:物件內可以建立資料、功能 (函式)
物件
let person = {
name: "Laura",
age: 16,
address: {
city: "Taipei",
country: "Taiwan"
}
};
person.email = "Laura@example.com"; // 新增屬性以及值
Logger.log(person.name); // Laura
Logger.log(person.address.city); // Taipei
物件操作,獲取所有屬性名稱、值
物件
let person = {
name: "Laura",
age: 16,
address: {
city: "Taipei",
country: "Taiwan"
}
};
let objectKeys = Object.keys(person); // [name, age,adress]
let objectValues = Object.values(person); // [Laura, 16.0, {city=Taipei, country=Taiwan}]
日期建立、基本操作
此為完整的表準日期格式:
Sun Apr 12 13:28:56 GMT+0800 (CST)
日期
let now = new Date(); // 獲取現在日期
let newDate1 = new Date(2008, 3, 12, 13, 28, 56); // 建立日期 Sun Apr 12 13:28:56 GMT+08:00 2008
let newDate2 = new Date(2008, 3, 12); // 可省略後面參數,自動設為 0
let newYearDate new Date("2025-01-29") // 字串轉換日期,支援可以被 parse() 的字串格式
Logger.log(now.getFullYear()); // 2025
Logger.log(now.getMonth()); // 0-11
Logger.log(now.getDate()); // 1-31
Logger.log(now.getDay()); // 0-6 (週日-週六)
Logger.log(now.getHours()); // 0-23
Logger.log(now.toLocaleDateString()); // 本地日期字串
let tomorrow = new Date(now.getTime() + 24*60*60*1000);
let diffDays = Math.floor((tomorrow - now) / (24*60*60*1000));
函式
// 基本函式
function basicFunction(a, b) {
return a + b;
}
const basicFunction = function(a, b){
return a + b ;
}
// 箭頭函式
const arrowFunction = (a, b) => {
return a + b;
};
// 只有回傳值可以簡寫成這樣
const arrowFunction = (a, b) => a + b;
// 呼叫函式
Logger.log(arrowFunction(10, 20)); // 30
函式名稱
參數
運算子
算數運算子與 C++ 的寫法基本相同,這邊簡單說明比較運算子的部分。
運算子 | 說明 | 舉例 |
---|---|---|
== | 等於 | 3 == '3' (true) |
!= | 不等於 | 3 != 2 (true) |
=== | 全等(等於並且型別相等) | 3 === '3' (false) |
!== | 不全等 | 2 !== '2' (true) |
> | 大於 | 3 > 2 (true) |
< | 小於 | 3 < 4 (true) |
>= | 大於等於 | 3 >= 3 (true) |
<= | 小於等於 | 4 <= 4 (true) |
判斷式
// if 條件判斷
if (condition) {
// 程式
} else if (anotherCondition) {
// 程式
} else {
// 程式
}
// switch 條件判斷
switch (value) {
case 1: // 當 value 等於 1,執行程式
// 程式
break;
case 2:
// 程式
break;
default:
// 程式
}
迴圈
let arr = [1, 2, 3, 4];
for (let i = 0; i < arr.length(); i++){
Logger.log(arr[i]);
} // 1, 2, 3, 4
for(let key in arr){
Logger.log(key);
} // 0, 1, 2, 3
for(let item of arr){
Logger.log(item);
} // 1, 2, 3, 4
for...in 迴圈拿來遍歷物件的 Key 放在陣列上的話就是索引值。
for...of 迴圈拿來遍歷物件的 Value 以陣列來說就是儲存的值。
迴圈
let arr = [1, 2, 3, 4];
let i = 0;
while (i < arr.length()) {
Logger.log(arr[0]);
i++;
}
do {
Logger.log(arr[0]);
i++;
} while (i < arr.length());
do...while 迴圈是先執行一次再判斷,while判斷式後面記得加分號。
JavaScript
基礎語法完結!!!

Google apps script語法
呵呵終於要進入正題了
Index
一打開長這樣
GAS
function myFunction() {
// 程式寫在這,GAS 每個 function 單獨執行
}
// 後面可以寫別的函式,並且可以獨立執行。
開啟試算表
試算表
// 取得活動中的試算表
let spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
let sheet = spreadsheet.getActiveSheet(); // 獲取活動中工作表
// 開啟試算表
let spreadsheet = SpreadsheetApp.openById('試算表ID');
let sheets = spreadsheets.getSheets(); // 獲取所有工作表
當你的 .gs 檔有跟試算表連在一起,並且試算表開啟的時候可以直接獲取活動中的試算表。
否則通常完整的寫法使用 id 開啟試算表。
建立新試算表
試算表
// 建立新試算表並命名
let newSpreadsheet = SpreadsheetApp.create('試算表名稱');
// 建立新工作表
let newsheet = newSpreadsheet.insertSheet('newSheet');
// 獲取試算表 id
let spreadsheetId = newSpreadsheet.getId();
// 獲取試算表 URL
let spreadsheetUrl = newSpreadsheet.getUrl();
讀取儲存格
試算表
let spreadsheet = SpreadsheetApp.openById('試算表ID');
let sheets = spreadsheets.getSheets(); // 獲取所有工作表,以陣列儲存
// 讀取儲存格資料
// 讀取單一儲存格
let value = sheets[0].getRange("A1").getValue();
let value = sheets[0].getRange(1, 1).getValue(); // 同上,使用儲存格座標
// 讀取多個儲存格
let values = sheets[0].getRange("A1:B5").getValues();
let values = sheets[0].getRange(1, 1, 5, 2).getValues(); // 同上,使用儲存格座標
讀取多個儲存格時,將資料轉換成陣列。
寫入儲存格
試算表
let spreadsheet = SpreadsheetApp.openById('試算表ID');
let sheets = spreadsheets.getSheets(); // 獲取所有工作表,以陣列儲存
// 寫入儲存格資料
// 寫入單一儲存格
sheets[0].getRange("A1").setValue("新資料");
// 寫入多個儲存格
let data = [["姓名", "年齡"], ["小明", 3]];
sheets[0].getRange(1, 1, 2, 2).setValues(data);
1,1 (A1) | 1,2 (B1) | 1,3 (C1) | 1,4 (D1) | 1,5 (E1) |
2,1 (A2) | 2,2 (B2) | 2,3 (C2) | 2,4 (D2) | 2,5 (E2) |
3,1 (A3) | 3,2 (B3) | 3,3 (C3) | 3,4 (D3) | 3,5 (E3) |
傳送郵件
GMail
// 發送郵件一
GmailApp.sendEmail(
"recipient@example.com",
"郵件主旨",
"郵件內容"
);
// 發送郵件二
MailApp.sendEmail(
"recipient@example.com",
"郵件主旨",
"郵件內容"
);
// 字串轉換
`${變數}`
GmailApp vs MailApp
GMail
功能 | GmailApp | MailApp |
---|---|---|
傳送郵件 | ||
寄件備份 | ||
讀取郵件 | ||
搜尋、刪除郵件 | ||
傳送附件 | ||
是否需要授權 | ||
傳送上限 |
|
個人:100 封
Workspace:1500 封
個人:100 封
Workspace:1500 封
Gmail
缺點
- 不會保留寄件副本
- 無法存取 Gmail 郵件、標籤
優點
- 適合傳送簡單郵件,方便快速
- 不需要 Gmail 權限
MailApp
使用情境
不需要存取 Gmail 郵件
不想或不能請求權限
正在 Google Workspace 環境中
Gmail
缺點
- 需要 Gmail 權限
- 較為適合個人帳號
優點
- 可以操作進階 Gmail 功能
- 寄件後會保留備份
- 可以發送附件
GmailApp
使用情境
需要保留寄件備份
需要讀取、搜尋、刪除郵件,或修改標籤
需要傳送附件
傳送 HTML 格式郵件
也可以用 MailApp
GMail
// 發送 HTML 格式郵件
GmailApp.sendEmail(
"recipient@example.com",
"郵件主旨",
"",
{htmlBody: "把 HTML <body> 內容搬過來"}
);
也可以把整個 HTML 標籤內所有東西搬過來,這樣就可以使用內嵌 CSS 以及 JS,不過不保證成功。
搜尋郵件
GMail
// 搜尋來自指定寄件人的郵件
let threads = GmailApp.search('from:example@example.com');
搜尋條件
'suject:remind' 搜尋特定主題的郵件
'has:word' 搜尋包含特定文字的郵件
'to:Laura@example.com' 搜尋特定收件人的郵件
獲取郵件內容
GMail
// 搜尋來自指定寄件人的郵件
let threads = GmailApp.search('from:example@examp');
threads.forEach((thread)=>{
let messages = thread.getMessages();
messages.forEach((message)=>{
let subject = message.getSubject();
Logger.log('主題: + `${subject}`');
})
})
讀取資料
getFrom(), getTo(), getDate(), getBody(), getSubject()
收件人 寄件人 日期 郵件內容 主旨
建立一個試算表,裡面包含一些人物資訊,至少有姓名跟郵件(可以借你隔壁的用一下),請依據試算表內容發出至少兩封信件,信件裡面須包含試算表裡的資訊。
小實作
必須包含主旨,其餘內容不拘,舉例:XXX您好,這是一封測試信。
Google Form 同樣可以直接建立一個與其連結的 Apps Script ,並且其本身可以建立試算表,獲取資料的方式就和前面所說的相同。
form
// 建立新表單
function createNewForm(formName) { // 呼叫函式時需包含一個參數 formName
let newForm = FormApp.create(formName); // 建立新的表單
let formId = newForm.getId(); // 獲取新表單的 id
return formId ; // 回傳 id,是一個字串
}
// 以 id 開啟表單
let form = FormApp.openById(formId);
// 開啟活動中的表單
let form = FormApp.getActiveForm();
Google Form 建立時,在獲取 URL 的時候比較特殊,分為編輯以及填寫兩種連結。
form
// 建立表單
function createNewForm(formName) { // 呼叫函式時需包含一個參數 formName
let newForm = FormApp.create(formName); // 建立新的表單
let editUrl = newForm.getEditUrl(); // 獲取編輯連結
let publishedUrl = newForm.getPublishedUrl(); // 獲取公開連結
let Urls = {
edit: editUrl,
published: publishedUrl
}; // 建立 Url 物件,儲存兩種連結。
return Urls ; // 回傳
}
建立問題(這裡以單選問題舉例)
form
// 建立新問題
let form = FormApp.openById(id);
let item = form.addMultipleChoiceItem();
item.setTitle("你最喜歡的動物?");
item.setChoices([item.createChoise("貓"), item.createChoise("狗")]);
item.showOtherOption(true);
還可以建立什麼?
多選題
簡答題
下拉選單
勾選方塊
圖片
標題
段落題
多選網格題
影片
單選網格題
獲取表單回應
form
function getFormResponses() {
let form = FormApp.getActiveForm();
let responses = form.getResponses();
responses.forEach((response) => {
let answers = response.getItemResponses();
answers.forEach((answer) => {
Logger.log("問題:" + answer.getItem().getTitle());
Logger.log("回應:" + answer.getResponse());
});
});
建立一個表單(用 Apps Script) ,裡面可以填寫日期、科目、成績,根據表單結果每日自動化發送成績報表郵件給自己 (你想傳給你們班導或爸媽我也沒意見)
小實作
建立新行事曆活動
Calendar
function createCalendarEvent() {
let calendar = CalendarApp.getDefaultCalendar(); // 取得預設行事曆
calendar.createEvent("GAS課", // 事件標題
new Date(2025, 1, 4, 9, 0), // 開始時間(2025年2月4日 9:00)
new Date(2025, 1, 4, 12, 0), // 結束時間(2025年2月4日 12:00)
{ location: "北一女中學珠五樓電腦教室", description: "建北電資寒訓 GAS 課程.." } // 其他資訊
);
}
取得特定日期的所有活動
Calendar
function getEventsOnDate() {
let calendar = CalendarApp.getDefaultCalendar();
let startTime = new Date(2025, 1, 4); // 2 月 4 日
let endTime = new Date(2025, 1, 5); // 2 月 5 日(跨一天以取得當天所有事件)
let events = calendar.getEvents(startTime, endTime);
events.forEach(function(event) {
Logger.log("標題: " + event.getTitle() + ", 時間: " + event.getStartTime());
});
}
刪除特定事件
Calendar
function deleteEvent() {
let calendar = CalendarApp.getDefaultCalendar();
let startTime = new Date(2025, 1, 5, 10, 0);
let endTime = new Date(2025, 1, 5, 11, 0);
let events = calendar.getEvents(startTime, endTime);
events.forEach(function(event) {
if (event.getTitle() === "會議") { // 確保是要刪除的事件
event.deleteEvent();
Logger.log("已刪除事件:" + event.getTitle());
}
});
建立一個 Form (這邊為了方便可以手動建立),裡面是關於日程的問題,例如:活動名稱、時間、參與人...,根據此表單的填寫結果,自動化建立日歷活動。
小實作
Google Apps Script
WEB
可以寫後端!!!
可以架設網頁!!!

Step1:有一個 HTML 檔
Step2:引入到 Apps Script
WEB

Step3:寫好後端
WEB
function doGet() {
// 載入並返回 HTML 頁面
return HtmlService.createHtmlOutputFromFile('index');
// index 為網頁 html 名稱
}
Step4:部署
WEB

Step4:部署
編輯權限
WEB

獲得一個連結,然後就成功啦!!!
WEB

介紹 doGet 在幹嘛,主要功能就是回傳HTML 頁面,處理 HTTP GET 請求
WEB
function doGet() {
// 載入並返回 HTML 頁面
return HtmlService.createHtmlOutputFromFile('index');
// index 為網頁 html 名稱
}
接下來就可以用 GAS 處理網頁後端,我們可以結合試算表儲存資料。
與一般 HTML 的檔案不同的是,這裡的 script 寫在 head
WEB
<!DOCTYPE html>
<html>
<head>
<title>Google 試算表填寫</title>
<script>
function submitForm() {
let name = document.getElementById("name").value;
let email = document.getElementById("email").value;
google.script.run.withSuccessHandler(() => alert("提交成功!")).saveData(name, email);
}
</script>
</head>
<body>
<h1>請填寫資訊</h1>
<label>姓名:</label> <input type="text" id="name"><br>
<label>Email:</label> <input type="text" id="email"><br>
<button onclick="submitForm()">提交</button>
</body>
</html>
gs這樣寫
WEB
function doGet() {
return HtmlService.createHtmlOutputFromFile("index");
}
function saveData(name, email) {
let sheet = SpreadsheetApp.openById("你的試算表ID").getSheetByName("表單回應");
sheet.appendRow([name, email, new Date()]);
}
依樣畫葫蘆,把表單填寫內容結合 Gmail 傳送一個確認信件給填寫人。
小實作
參考資料
成發
每個人都要做一份個人的 GAS 成發呦~
進度追蹤系統
可以是各種進度,閱讀、跑步、念書、成績......
使用者填寫每日進度(可以用 form 或者 sheet)
每日提醒使用者更新進度
進度落後發送提醒訊息給使用者 (可以用我教過的郵件、或者 google 有自己的訊息系統可以嘗試看看)
定期生成圖表 (試算表功能) 傳送報告給使用者
成發
進階
把以上東西搬到網頁上,用 GAS 寫,可以參考完簡報後,寫 HTML 和 CSS。
其他
引入外部 API (可適當使用 AI 工具)
成發
Google Apps Script
By laura07110717
Google Apps Script
- 94