[Series Email] Bài 6: Gửi Email Theo Template Cho Sẵn
https://hocggsheet.com/gui-email-theo-template-cho-san/
Last updated
https://hocggsheet.com/gui-email-theo-template-cho-san/
Last updated
Gửi email theo template là một bài viết rất thú vị vì nó kết hợp nhiều kĩ năng và có tính ứng dụng cao trong thực tế. Mấu chốt giải quyết được yêu cầu này là phải viết được thuật toán thay thế tất cả các trường (trong Google Sheet) vào trong đoạn email template.
Template
Cho 1 template như trong hình. Mục đích của chúng ta là sẽ gửi email và thay thế những trường ở trong { } bằng dữ liệu ở sheet sau:
Dữ liệu chứa các trường cần thay thế
Và đây là kết quả mà chúng ta mong muốn:
Kết quả
dataRange – lấy dải ô chứa dữ liệu cần thay thế vào template
header – lấy dải ô chứa (tên) các trường
template – lấy template đã viết sẵn
012345678
function thaythe() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet1 = ss.getSheetByName('sheet1'); var dataRange = sheet1.getDataRange().getValues(); var header = sheet1.getRange(1,1,1,sheet1.getLastColumn()).getValues(); var templateSheet = ss.getSheetByName('template'); var template = templateSheet.getRange(1, 1).getValue();}
Ở đây mình dùng 2 vòng lặp for lồng nhau:
Vòng for thứ nhất, cho biến j lấy giá trị của các hàng trong dataRange
Vòng for thứ hai, cho biến i lấy giá trị của các cột trong header. Các cột này chính là các trường cần thay thế bằng dữ liệu trong dataRange
Lưu ý: trong vòng for thứ 2, chúng ta sử dụng header[0] bởi vì header sẽ có định dạng là mảng 2 chiều [[Email, Họ tên, Ngày bắt đầu, SĐT]]. Dùng header[0] sẽ lấy ra phần tử mẹ: [Email, Họ tên, Ngày bắt đầu, SĐT]
0123456
for (var j = 0; j<dataRange.length; j++) { //hàng var message = template; for (var i = 0; i<header[0].length; i++) { //cột message = message.replace("{"+header[0][i]+"}",dataRange[j][i]); }}
Kế tiếp, mình dùng biến message để lấy giá trị của ô template đã khai báo ở trên. Trong vòng lặp, sử dụng replace() để thay thế các trường header bằng dataRange.
Lưu ý: Nối chuỗi “{“+header[0][i]+”}” vì cái chúng ta muốn thay thế trong template là {tên trường} chứ không đơn thuần chỉ là tên trường
Tại sao cần thêm biến phụ message?
Dùng thêm 1 biến phụ để ghi đè lên template với mục đích để sau mỗi lần replace, biến message sẽ lấy kết quả replace lần trước để tiếp tục replace. Giả sử nếu không dùng biến phụ message:
Khi i = 0, header[0][0] = “scriptsheetvn@gmail.com”, kết quả sẽ được:
“Xin chào {Họ tên},
Khóa học bạn đã đăng ký sẽ bắt đầu vào ngày: {Ngày bắt đầu} Vui lòng xác thực thông tin liên lạc: Email: scriptsheetvn@gmail.com Số điện thoại liên lạc: {SĐT}
Nếu thông tin trên không đúng, vui lòng trả lời email này
Thân. HocGgSheet.com“
Khi i = 1, header[0][1] = “Nguyễn A”, kết quả sẽ được:
“Xin chào Nguyễn A,
Khóa học bạn đã đăng ký sẽ bắt đầu vào ngày: {Ngày bắt đầu} Vui lòng xác thực thông tin liên lạc: Email: {Email} Số điện thoại liên lạc: {SĐT}
Nếu thông tin trên không đúng, vui lòng trả lời email này
Thân. HocGgSheet.com”
Tiếp tục với i = 2, template sẽ không lấy kết quả vừa có được mà nó sẽ cứ lấy đi lấy lại giá trị template đã khai báo
Cuối cùng, sử dụng sendEmail() để gửi email theo template cho các email ở cột A sheet1, tiêu đề “Thư thông báo”, và nội dung chính là biến message ta vừa làm được ở trên
01
MailApp.sendEmail(dataRange[j][0], 'Thư thông báo', message);
012345678910111213141516
function thaythe() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet1 = ss.getSheetByName('sheet1'); var dataRange = sheet1.getRange(2, 1, sheet1.getLastRow()-1, sheet1.getLastColumn()); var header = sheet1.getRange(1,1,1,sheet1.getLastColumn()).getValues(); var templateSheet = ss.getSheetByName('template'); var template = templateSheet.getRange(1, 1).getValue(); for (var j = 0; j<dataRange.length; j++) { var message = template; for (var i = 0; i<header[0].length; i++) { message = message.replace("{"+header[0][i]+"}",dataRange[j][i]); } MailApp.sendEmail(dataRange[j][0], 'Thư thông báo', message); }}
Sử dụng đoạn code trên thôi đã đủ khiến bạn đạt được mục đích rồi. Tuy nhiên nó có 1 hạn chế. Đó là chương trình trên chỉ thay thế các {tên trường} một lần mà thôi. Có nghĩa là nếu template có 2 trường {Email} thì nó sẽ chỉ thay thế {Email} đầu tiên. Để khắc phục, chúng ta cần thêm 1 vòng lặp nữa để thay thế toàn bộ các trường trong template
Thêm biến x để lấy vị trí của {tên trường} bằng hàm indexOf(). Vòng lặp while sẽ lặp đến khi nào {tên trường} không còn trong template nữa (thay thế toàn bộ). Khi {tên trường} không còn trong template, x lúc này sẽ bằng -1. Vậy nên vòng lặp while sẽ chạy khi x>=0, và dừng khi x<0 (bằng -1)
012345678910
for (var j = 1; j<dataRange.length; j++) { var message = template; for (var i in header[0]) { var x = 0; while (x>=0) { message = message.replace("{"+header[0][i]+"}",dataRange[j][i]); x = message.indexOf("{"+header[0][i]+"}"); } }}
01234567891011121314151617181920
function thaythe() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet1 = ss.getSheetByName('sheet1'); var dataRange = sheet1.getRange(2, 1, sheet1.getLastRow()-1, sheet1.getLastColumn()); var header = sheet1.getRange(1,1,1,sheet1.getLastColumn()).getValues(); var templateSheet = ss.getSheetByName('template'); var template = templateSheet.getRange(1, 1).getValue(); for (var j = 1; j<dataRange.length; j++) { var message = template; for (var i in header[0]) { var x = 0; while (x>=0) { message = message.replace("{"+header[0][i]+"}",dataRange[j][i]); x = message.indexOf("{"+header[0][i]+"}"); } } MailApp.sendEmail(dataRange[j][0], 'Thư thông báo', message); }}