我已经多次遇到这个问题,并且我认为我有一个非常通用的解决方案。获取非嵌入图像也是一个问题。
我不确定我的解析是否比你的解析更脆弱。最后我把那部分吸出来了multipart
通过抓住以开头的周围的线'--'
。其他一切只是确保我下次需要时可以使用它而无需过多修改代码。我收到了一些电子邮件,但似乎不符合\r\n
并引起问题:需要注意的事情。
The getInlineImages
函数将获取消息的原始内容并返回一个对象数组。每个对象都会有 img 标签的 src 和与图像相关的 blob。如果您只想要内嵌图像,您可以选择忽略任何不以“cid”开头的内容。
The getBlobFromMessage
函数将获取消息的原始内容和 img 标签的 src(包括“cid”)并返回关联的 blob。
可以看到代码注释了here http://goo.gl/FeLQy.
function getInlineImages(rawContent) {
var url = /^https?:\/\//, cid = /^cid:/;
var imgtags = rawContent.match(/<img.*?>(.*?<\/img>)?/gi);
return imgtags ? imgtags.map(function(imgTag) {
var img = {src: Xml.parse(imgTag,true).html.body.img.src};
img.blob = url.test(img.src) ? UrlFetchApp.fetch(img.src).getBlob()
: cid.test(img.src) ? getBlobFromMessage(rawContent,img.src)
: null;
return img;
}) : [];
}
function getBlobFromMessage(rawContent,src) {
var cidIndex = src.search(/cid:/i);
if(cidIndex === -1) throw Utilities.formatString("Did not find cid: prefix for inline refenece: %s", src)
var itemId = src.substr(cidIndex + 4);
var contentIdIndex = rawContent.search("Content-ID:.*?" + itemId);
if(contentIdIndex === -1) throw Utilities.formatString("Item with ID %s not found.",src);
var previousBoundaryIndex = rawContent.lastIndexOf("\r\n--",contentIdIndex);
var nextBoundaryIndex = rawContent.indexOf("\r\n--",previousBoundaryIndex+1);
var part = rawContent.substring(previousBoundaryIndex,nextBoundaryIndex);
var contentTransferEncodingLine = part.match(/Content-Transfer-Encoding:.*?\r\n/i)[0];
var encoding = contentTransferEncodingLine.split(":")[1].trim();
if(encoding != "base64") throw Utilities.formatString("Unhandled encoding type: %s",encoding);
var contentTypeLine = part.match(/Content-Type:.*?\r\n/i)[0];
var contentType = contentTypeLine.split(":")[1].split(";")[0].trim();
var startOfBlob = part.indexOf("\r\n\r\n");
var blobText = part.substring(startOfBlob).replace("\r\n","");
return Utilities.newBlob(Utilities.base64Decode(blobText),contentType,itemId);
}