我在Google工作表上有一个简单的邮件合并脚本,可以正确发送电子邮件。我的邮件合并代码确实处理内嵌图像,但
1)它无法正常工作并显示“内嵌图像1”而不是实际的内嵌图像。在我的代码中,内嵌图像成为附件。
2)另外,如果我把占位符<> <>一起(即使中间有空格或逗号),它显示发送错误消息:“无法调用方法”替换“未定义”。可能是因为如果占位符在同一行上,则替换名称是错误的。
当2个占位符在同一行时,请参阅以下图像以获取错误代码:
发送和实际电子邮件消息,其中“内嵌图像1”应该是图像所在的位置:
这是我在Google工作表上进行邮件合并的代码,它取代了<<<< >>它与Google工作表中的列标题匹配,并与相应的值相匹配。有人可以就线内图像和占位符问题提出建议吗?非常感谢,谢谢!
//////////////////////////////////////////////////////////////////////////////
// Get inline images and make sure they stay as inline images
//////////////////////////////////////////////////////////////////////////////
var emailTemplate = selectedTemplate.getBody();
var rawContent = selectedTemplate.getRawContent();
var attachments = selectedTemplate.getAttachments();
var cc = selectedTemplate.getCc();
var bcc = selectedTemplate.getBcc();
var regMessageId = new RegExp(selectedTemplate.getId(), "g");
if (emailTemplate.match(regMessageId) != null) {
var inlineImages = {};
var nbrOfImg = emailTemplate.match(regMessageId).length;
var imgVars = emailTemplate.match(/<img[^>]+>/g);
var imgToReplace = [];
if(imgVars != null){
for (var i = 0; i < imgVars.length; i++) {
if (imgVars[i].search(regMessageId) != -1) {
var id = imgVars[i].match(/realattid=([^&]+)&/);
if (id != null) {
var temp = rawContent.split(id[1])[1];
temp = temp.substr(temp.lastIndexOf('Content-Type'));
var imgTitle = temp.match(/name="([^"]+)"/);
if (imgTitle != null) imgToReplace.push([imgTitle[1], imgVars[i], id[1]]);
}
}
}
}
for (var i = 0; i < imgToReplace.length; i++) {
for (var j = 0; j < attachments.length; j++) {
if(attachments[j].getName() == imgToReplace[i][0]) {
inlineImages[imgToReplace[i][2]] = attachments[j].copyBlob();
attachments.splice(j, 1);
var newImg = imgToReplace[i][1].replace(/src="[^\"]+\"/, "src=\"cid:" + imgToReplace[i][2] + "\"");
emailTemplate = emailTemplate.replace(imgToReplace[i][1], newImg);
}
}
}
}
//////////////////////////////////////////////////////////////////////////////
var mergeData = {
template: emailTemplate,
subject: selectedTemplate.getSubject(),
plainText : selectedTemplate.getPlainBody(),
attachments: attachments,
inlineImages: inlineImages,
name: name,
from: from,
cc: cc,
bcc: bcc
}
var objects = getRowsData(dataSheet, dataRange);
Logger.log(objects);
for (var i = 0; i < objects.length; ++i) {
var rowData = objects[i];
if (rowData.mergeStatus != "Done" && rowData.mergeStatus != "0") {
try {
processRow(rowData, kind, mergeData);
dataSheet.getRange(i + 2, headers.indexOf('Merge status') + 1).setValue("Done").clearFormat().setComment(new Date());
}
catch (e) {
dataSheet.getRange(i + 2, headers.indexOf('Merge status') + 1).setValue("Error").setBackground('red').setComment(e.message);
}
}
}
}
function processRow(rowData, kind, mergeData) {
var emailText = fillInTemplateFromObject(mergeData.template, rowData);
var emailSubject = fillInTemplateFromObject(mergeData.subject, rowData);
var plainTextBody = fillInTemplateFromObject(mergeData.plainText, rowData);
mergeData['htmlBody'] = emailText;
if(rowData.cc != undefined) mergeData.cc = rowData.cc;
if(rowData.bcc != undefined) mergeData.bcc = rowData.bcc;
//GmailApp.sendEmail(rowData.email, emailSubject, emailText); //sends in html code
//GmailApp.sendEmail(rowData.email, emailSubject, plainTextBody, emailText); //sends in plainText
GmailApp.sendEmail(rowData.email, emailSubject, plainTextBody, mergeData); //sends but in-line images appear as attachments with a line inline images 1 on where the img should have been at
//GmailApp.sendEmail(rowData.email, emailSubject, mergeData); //sends only "[object Object]"
}
// Replaces markers in a template string with values define in a JavaScript data object.
// Arguments:
// - template: string containing markers, for instance <<Column name>>
// - data: JavaScript object with values to that will replace markers. For instance
// data.columnName will replace marker <<Column name>>
// Returns a string without markers. If no data is found to replace a marker, it is
// simply removed.
function fillInTemplateFromObject(template, data) {
template = template.replace(/<</g, '<<');
template = template.replace(/>>/g, '>>');
var email = template;
template = template.replace(/">/g, "~");
// Search for all the variables to be replaced, for instance <<Column name>>
var templateVars = template.match(/<<[^\>]+>>/g);
if (templateVars != null) {
if (template.match(/\<\<[^\%]+\>>/g) != null) {
templateVars = templateVars.concat(template.match(/\<\<[^\%]+\>>/g));
}
}
else {
var templateVars = template.match(/\<\<[^\%]+\>>/g);
}
if (templateVars != null) {
// Replace variables from the template with the actual values from the data object.
// If no value is available, replace with the empty string.
for (var i = 0; i < templateVars.length; ++i) {
// normalizeHeader ignores <<>> so we can call it directly here.
var variableData = data[normalizeHeader(templateVars[i].replace(/<[^\~]+~/, ''))];
variableData = variableData.replace(/\r?\n/g, "<br />")
templateVars[i] = templateVars[i].replace(/~/g, '">');
// Check that we have a header for this merge field
if (variableData == undefined) {
throw new UserException("Undefined merge field " + templateVars[i]);
}
email = email.replace(templateVars[i], variableData || "");
}
}
return email;
}
// Exception
function UserException(message) {
this.message = message;
this.name = "UserException";
}