如果你很急著用,可以直接使用這份 Add-On: Merge Mail,其好處是還會告訴你使用者有沒有開啟 Email,但免費版好像一天一個帳號只能寄給 50 人。自己寫的好處是,如果你一天突然要寄很多封(20,000封 and 100人以內)且還有個五分鐘,那可以持續閱讀。對於想知道怎麼做的人,讓我們開始吧!
先來個小測驗
答案會在今天的文章中!
目標
現在幾乎每天都會打開 Gmail,但有時就是會需要寄一些客製化的 Email 給客戶。此時就會遇到個問題。
- 「我要怎麼設定客製化的 Email」?
- 「我要怎麼結合客製化 Email 和 Google Form / Sheet?」?
特別提醒,這邊的「客製化」Email,因為會限定是要 Google 產品,一般人會是 Gmail,或是企業與組織的 Google Workspace(簡單來說你的學校、組織的基本上是用 Google Drive 傳檔案的話,基本上就是)。那我們就開始吧!
Q1 我要怎麼設定客製化的 Email?
Step 1 從 Google Sheet 中打開你的表單
在寄客製化 Email 時通常都要有個清單,這邊就來綁定一個 Google Sheet,所以第一步是打開一份 Google Sheet。
一樣提醒要按下「允許授權」。
Step 2 準備好寄送 Email 要用的 Code
在寄送 Email 上,我們透過的是 MailApp.sendEmail()
的功能。寫上收信人、主旨與內文,按下執行就可以了(就是這麼簡單)。
function sendEmails() {
let emailAddress = "test@gmail.com";
let subject = "Sending emails from a Spreadsheet";
let message = "This is a test for sending email";
MailApp.sendEmail(emailAddress, subject, message);
}
另外也有「回覆」可以使用:sendEmail(to, replyTo, subject, body)
Step 3 在 Google 表單上填寫要寄的名單
首先先創造一系列要寄出的內容,這邊我就大概創了一個表單。
接著我們要在 GAS 中讀取這表單的內容。完整的程式碼在這,待會我們會一段段分段來理解。
function sendEmails() {
// 讀取連結的 Google Sheet 中的 Tab
let sheet = SpreadsheetApp.getActiveSheet();
let startRow = 2;
let numRows = 5;
let startCol = 2;
let numCols = 4;
let dataRange = sheet.getRange(startRow, startCol, numRows, numCols);
let data = dataRange.getValues();
for (let i in data) {
let row = data[i];
let receiver = row[0]
let emailAddress = row[1];
let subject = row[2] + ' '+ receiver;
let message = row[3];
MailApp.sendEmail(emailAddress, subject, message);
}
}
執行以後,你就會在「寄件備份」中看到五個已經寄出的信件。因為是假的 email address,所以你也會馬上收到一份「寄件錯誤」的通知。
接下來我們一條條看。
Step 3-1 Spreadsheet
vs Sheet
首先是第一段:「讀取工作表」let sheet = SpreadsheetApp.getActiveSheet();
回到最一開始的測驗,要怎麼分試算表與工作表呢?用英文來理解會比較有幫助,Spread
有「擴大、蔓延之意」,sheet
則是「一片、單張」。進而可以推測說,sheet
是指單張的「工作表」,spreadsheet
指的是全部的工作表,也就是中文的「試算表」。
Step 3-2 getRange()
的 Row(列) 和 col(行)
再來第二段:「選定要讀取的資料範圍」
let startRow = 2;
let numRows = 5;
let startCol = 2;
let numCols = 4;
let dataRange = sheet.getRange(startRow, startCol, numRows, numCols);
再來是也是重要觀念,到了指定的 Sheet 後,要怎麼用 getRange()
抓行(Col)與列(Row)呢?這邊的關鍵是「 用SpreadSheet 原本的 Index 」,或是我們會稱為 根據 R1C1 位置參照樣式(R1C1 notation),可以理解成 Row(列) 和 col(行)都以 1 為開始,且以最左上角起始點為「R=1,C=1」。
那我們這邊是直接設定好要抓的行數與列數,如果想要比較彈性地去抓,可以將 numRows 設定為 numRows = sheet.getLastRow() - startRow
,這個公式會幫我們 getLastRow()
抓出表單中最下面有數值的「那一列」。直的欄也同理可用 getLastColumn()
,想看使用範例可以參考 D11。
Step 3-3 getValues()
時抓下來的是 Array of Array
再來第三段:「從選定的範圍中取得資料」
let data = dataRange.getValues();
這個也是超重要觀念之一,在我們用 getValues
抓下來的數值會是 Array in Array,或是說 2 dimentional array,長起來的樣子會是這樣。
所以,如果我今天要抓值 Dave
的話,我需要輸入的會是 data[3][0]
;要抓 Amy
那列的 Hellow World
的話,就要用 data[0][3]
。因為這邊不再是 Sheet 內的資料了,而是回到資料結構;因此不再遵循 R1C1,而是回到程式最原本的第一項 index 是 0。
Step 3-4 給予「客製化」的內容(ㄧ) — 直接寫在程式上
在給予客製化的內容部分有兩種做法,第ㄧ種是用程式,另一是直接在表單中先搞定。以下先示範第一種。
for (let i in data) {
let row = data[i];
let receiver = row[0]
let emailAddress = row[1];
let subject = row[2] + ' '+ receiver;
let message = row[3];
MailApp.sendEmail(emailAddress, subject, message);
}
這種很單純就是藉由 let subject = row[2] + ' '+ receiver;
在 subject 的部分加上直接加上收件者的名字。這種是在開發時寫得快,但對於不熟悉的人來說,這種方式很容易會出現資料結構上的警示(像是數字沒有轉成字串等等),所以個人會建議先在 Google Sheet 先把內容確認。
Step 3-4 給予「客製化」的內容(二) — 先在表單上完成
先新增一欄,放要寄出的 Subject。這時我們就可以用 concatenate
來把字串做合併,用法是像這樣 CONCATENATE("歡迎", "使用", "試算表!")
,調整內文也是同樣的道理。
並在這時回到表單中,因為新增了一欄,所以記得調整參數也要調整(numsCol
要 +1,for 迴圈內要調整成如下面這樣)。
for (let i in data) {
let row = data[i];
let receiver = row[0]
let emailAddress = row[1];
let subject = row[3];
let message = row[4];
MailApp.sendEmail(emailAddress, subject, message);
}
好,那基本上這樣做完,就已經完成了「客製化寄信」的第一堂了,功能性基本上都有。但要怎麼樣跟 Google 表單結合呢?
要怎麼結合客製化 Email 和 Google Form / Sheet
因為 Google Sheet 的結合在 Q1 已經解釋了,這邊就針對說明怎麼樣讓「Google 表單」串接客製化 Email。其實也沒有什麼特殊功能,就是讓 讓 Google 表單連到一個 Google Sheet,再用 Google Sheet 寄出(重複 Q1)。大致的作法可以參閱這一份,當然程式碼要調整一下就是。
Reference
Tutorial: Sending emails from a Spreadsheet
一樣提醒,寄信有 Quota 限制——每天不超過20,000封,也不超過100人。
完整的程式碼在 Step 3。明天 D5 會繼續介紹結合 Email 中寄出 HTML 的使用方式,如果不想錯過可以訂閱按讚小鈴鐺(?),也歡迎留言跟我說你還想知道什麼做法/主題。如果還有問題,透過留言之外,也可以到 Facebook Group,想開很久這次鐵人賽才真的開起來哈哈哈,歡迎來當 Founding Member。我們明天見。