2012-07-31 204 views
1

我正在修改Google Apps脚本中的邮件合并项目。我面临的问题是如何使电子邮件正文显示内嵌图像。目前,在调用GmailApp.sendEmail()之后,原始电子邮件模板中的所有内嵌图像将显示为附件。将JavaScript数组转换为JSON对象

我的猜测是,内嵌图像,如果我找到一些方式来imgVars数组转换成这样的JSON对象(从example in GAS documentation拍摄)显示:

MailApp.sendEmail(
    "[email protected]", 
    "Logos", 
    "", 
    { htmlBody: 
     "inline Google Logo<img src='cid:googleLogo'> images! <br/> inline YouTube Logo <img src='cid:youTubeLogo'>", 
    inlineImages: 
    { googleLogo: googleLogoBlob, 
     youTubeLogo: youtTubeLogoBlob 
    } 
    } 
); 

所以我尝试做的是转换一个这样的数组:

var array = { item1, item2, item3 }; 

要JSON对象是这样的:

var json = { item1Name: item1, 
      item2Name: item2, 
      item3Name: item3 
      }; 

下面是从邮件合并的代码片段我工作:

//--------------------------------------------------------------- 
    // If there are inline images in the body of the email 
    // Find them and store them in an array, imgVars 
    //--------------------------------------------------------------- 
    if(emailTemplate.search(/<\img/ != -1)) { 
    var inlineImages = {}; 

    // Extract all images from the email body 
    var imgVars = emailTemplate.match(/<img[^>]+>/g); 

    // For each image, extract its respective title attribute 
    for (i in imgVars) { 
    var title = imgVars[i].match(/title="([^\"]+\")/); 
    if (title != null) { 
    title = title[1].substr(0, title[1].length-1); 
    for (j in attachments) { 
     if (attachments[j].getName() == title) { 
     inlineImages[title] = attachments[j].copyBlob(); 
     attachments.splice(j,1); 
     } 
    } 
    var newImg = imgVars[i].replace(/src="[^\"]+\"/,"src=\"cid:"+title+"\""); 
    emailTemplate = emailTemplate.replace(imgVars[i],newImg); 
    } 
    } 
} 

objects = getRowsData(dataSheet, dataRange); 
for (var i = 0; i < objects.length; ++i) { 
    var rowData = objects[i]; 
    if(rowData.emailSent != "EMAIL_SENT") { 

    // Replace markers (for instance ${"First Name"}) with the 
    // corresponding value in a row object (for instance rowData.firstName). 

    var emailText = fillInTemplateFromObject(emailTemplate, rowData);  
    var emailSubject = fillInTemplateFromObject(selectedTemplate.getSubject(), rowData); 

    GmailApp.sendEmail(rowData.emailAddress, emailSubject, emailText, 
         {name: e.parameter.name, 
         attachments: attachments, 
         htmlBody: emailText, 
         cc: cc, 
         bcc: bcc, 
         inlineImages: inlineImages});  
+1

您确定要创建** JSON **或只是一个JavaScript对象吗?你的第一个代码示例只显示一个对象。而实际上你的问题是什么?你没有问过任何问题。 – 2012-07-31 23:49:06

+0

啊,到底是什么。让我们将对象文字重命名为JSON对象。 ':P' – 2012-08-01 01:49:52

+0

噢,问题是如何我应该内联的图像阵列,以便它可以采取如在GmailApp.sendEmail()可选的参数的inlineImages参数格式。我不确定它是否应该是JSON或JavaScript对象,但我的猜测是它是一个JavaScript对象。 – KarBytes 2012-08-01 19:59:56

回答

1

一些评论:

> var array = { item1, item2, item3 }; 

即语法不正确,数组文本应该是:

var array = [ item1, item2, item3 ]; 

[...]

> if (emailTemplate.search(/<\img/ != -1)) { 

反斜杠之前img是不必要的,模式应该是后面有个空格更好,不区分大小写(因为HTML不区分大小写,通常带有大写字母标记名称),所以/<img /i

> var imgVars = emailTemplate.match(/<img[^>]+>/g); 

解析HTML如果使用正则表达式不是一个好主意,将HTML转换为文档片段并处理它更好。

> var imgVars = emailTemplate.match(/<img[^>]+>/g); 

注意String.prototype.match返回一个数组。

> for (i in imgVars) { 

使用for..in以与阵列不推荐用于多种原因,例如可能不以任何特定次序返回的部件(其可以是不同的浏览器不同)和的for..in将返回数组中的所有枚举的属性和它的[[Prototype]]所以如果你在浏览器中已经有Array.prototype由“垫片”或“猴子补丁”,那么这些属性也将被列举的修改,所以:

> var title = imgVars[i].match(/title="([^\"]+\")/); 

很可能会试图呼叫匹配对属性的值是一个引用因为这是一个函数,所以抛出一个错误。至少应该包括一个hasOwnProperty测试,但最好只使用plain for循环。

> for (j in attachments) { 

看来附件是一个数组太多,所以使用普通的for循环在这里也以同样的理由如上述。这也不是一个好主意。(可能会以意想不到的顺序访问房产),拼接,推断您期待特定订单。请注意,在某些浏览器中,for..in会按照它们添加到数组中的顺序访问数组成员,而不是按数字顺序访问。其他浏览器将始终以特定顺序访问数字属性,但不会访问其他浏览器。

这在很大程度上会简单得多,如果HTML被转换成文档片段,然后DOM方法可以用于提取在img要素和访问他们的属性来建立一个对象。然后可以使用本地方法将对象转换为JSON(如果需要)。

1

草稿或罐头响应的100%保真度是完全可行的。此代码段是从工作邮件合并我扩展,以支持内嵌图像(包括嵌入式斑点和外部参考)和附件,以及:

... 
//selectedTemplate is a Gmail Message (draft/canned response) 
var emailTemplate = selectedTemplate.getBody(); 
var attachments = selectedTemplate.getAttachments(); 
var to = selectedTemplate.getTo(); 
var cc = selectedTemplate.getCc(); 
var bcc = Session.getActiveUser().getEmail(); 

if(emailTemplate.search(/<\img/ != -1)){ 
    var inlineImages = {}; 
    var imgVars = emailTemplate.match(/<img[^>]+>/g); 
    for(i in imgVars){ 
     var title = imgVars[i].match(/title="([^\"]+\")/); 
     if (title) { 
     title = title[1].substr(0, title[1].length-1); 
     var titleEncoded = title.replace(/ /g,"-"); 
     for(j in attachments){ 
      if(attachments[j].getName() == title){ 
      inlineImages[titleEncoded] = attachments[j].copyBlob().setName(titleEncoded); 
      attachments.splice(j,1); 
      } 
     } 
     var newImg = imgVars[i].replace(/src="[^\"]+\"/,"src=\"cid:"+titleEncoded+"\""); 
     emailTemplate = emailTemplate.replace(imgVars[i],newImg); 
     } 
    } 
    } 
... 
GmailApp.sendEmail(...., 
        {attachments: attachments, ..., 
        inlineImages: inlineImages}); 

我有这个与域用户工作了一整天,每一天。希望这可以帮助。

+0

谢谢Peter:D!这是很好的代码,但不幸的是,内嵌图像依旧会出现在邮件正文为空白矩形。也许有什么毛病我用草案/罐头回应。 – KarBytes 2012-08-03 15:36:04

+0

请尝试新的草案,如果问题仍然存在,编辑的问题,并张贴您所使用的代码。 – 2012-08-03 22:32:26

0

不幸的是,内嵌图片没有标题。他们有一个alt =嵌入式图像1,但这不同于附件的名称。 img标签中的唯一项目是alt和src。

鉴于这种情况,似乎没有被任何方式对内嵌图像领带到其他附件,而不是希望,第一个行内的图像是第一个附件等

我要指出,我使用Gmail网络界面创建草稿,并通过“插入图像”实验室插入图像。