[Series Email] Bài 6: Gửi Email Theo Template Cho Sẵn

https://hocggsheet.com/gui-email-theo-template-cho-san/

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.

1. Mô tả ví dụ

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:

Và đây là kết quả mà chúng ta mong muốn:

2. Thuật toán gửi email theo template

Khai báo

  • 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();}

Vòng lặp

Ở đâ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

Thêm lệnh gửi email

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);

Code hoàn chỉnh

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); }}

3. Nâng cấp

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]+"}"); } }}

Code hoàn chỉnh

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); }}

Last updated

Navigation

Lionel

@Copyright 2023