function sendMailMerge() { const ss = SpreadsheetApp.getActiveSpreadsheet(); const sheet = ss.getSheetByName("Test"); const data = sheet.getDataRange().getValues(); const headers = data.shift(); const nameIndex = headers.indexOf("Họ tên"); const emailIndex = headers.indexOf("Email"); if (nameIndex === -1 || emailIndex === -1) { throw new Error("Could not find 'Họ tên' or 'Email' in the header row."); } const docId = '1tTD00wA1qOqACEQdFhl1N9Glh57igpemM9Vczt2mEMA'; // 1. Get the Doc content as HTML instead of plain text const docHtmlTemplate = convertDocToHtml(docId); data.forEach(row => { const recipientName = row[nameIndex]; const recipientEmail = row[emailIndex]; if (recipientEmail) { // 2. Replace placeholders within the HTML string let emailHtml = docHtmlTemplate; emailHtml = emailHtml.replace(/{{Họ tên}}/g, recipientName); emailHtml = emailHtml.replace(/{{Email}}/g, recipientEmail); MailApp.sendEmail({ to: recipientEmail, subject: "Giải pháp chăm sóc khách hàng đa kênh giúp tăng năng suất vượt trội", htmlBody: emailHtml }); } }); } /** * Helper function to convert Google Doc body to basic HTML */ function convertDocToHtml(docId) { const doc = DocumentApp.openById(docId); const body = doc.getBody(); let html = ""; const numChildren = body.getNumChildren(); for (let i = 0; i < numChildren; i++) { const child = body.getChild(i); const type = child.getType(); if (type === DocumentApp.ElementType.PARAGRAPH) { html += "

"; html += processTextElement(child.asParagraph()); html += "

"; } else if (type === DocumentApp.ElementType.LIST_ITEM) { html += "
  • " + processTextElement(child.asListItem()) + "
  • "; } // Note: You can add logic here for Tables if your Doc uses them. } return html; } /** * Extracts text and applies styling (Bold, Italic, Link, Color) */ function processTextElement(container) { let textHtml = ""; const textObj = container.editAsText(); const textString = textObj.getText(); if (!textString) return "
    "; const indices = textObj.getTextAttributeIndices(); for (let i = 0; i < indices.length; i++) { const start = indices[i]; const end = (i + 1 < indices.length) ? indices[i + 1] : textString.length; let part = textString.substring(start, end); // Escape basic HTML characters to prevent breaking the layout part = part.replace(/&/g, "&").replace(//g, ">"); const bold = textObj.isBold(start); const italic = textObj.isItalic(start); const underline = textObj.isUnderline(start); const url = textObj.getLinkUrl(start); const color = textObj.getForegroundColor(start); let style = ""; if (bold) part = "" + part + ""; if (italic) part = "" + part + ""; if (underline) part = "" + part + ""; if (color) style += `color: ${color};`; if (style) part = `${part}`; if (url) part = `${part}`; textHtml += part; } return textHtml; }