从Gmail原始内容中解析内联图像

Fau*_* R. 6 google-apps-script

Gmail邮件getAttachments功能未返回内联图片 - 请参阅问题2810 https://code.google.com/p/google-apps-script-issues/issues/detail?id=2810

我需要这样做,所以我编写了下面的代码,以消息原始内容解析blob格式的内嵌图像,事先知道消息中的图像cid.

但是,我觉得这个解析在我找到base64图像内容中的第一个和最后一个字符的方式上非常脆弱,不是吗?

有没有更好的方法呢?

此致,Fausto

var rawc = message.getRawContent();
var b64c1 = rawc.lastIndexOf(cid) + cid.length + 3; // first character in image base64
var b64cn = rawc.substr(b64c1).indexOf("--") - 3; // last character in image base64
var imgb64 = rawc.substring(b64c1, b64c1 + b64cn + 1); // is this fragile or safe enough?
var imgblob = Utilities.newBlob(Utilities.base64Decode(imgb64), "image/jpeg", cid); // decode and blob
Run Code Online (Sandbox Code Playgroud)

小智 6

我已经多次遇到这个问题了,我想我有一个非常普遍的案例解决方案.获取非嵌入式图像也是一个问题.

我不确定我的解析是否比你的解析更脆弱.最后,我multipart通过抓住开头的周围线条来吸取部分内容'--'.其他一切只是确保我可以使用它而不需要在下次需要时修改代码.我有一些电子邮件似乎没有跟随\r\n并导致问题:需要注意的事项.

getInlineImages函数将获取消息的原始内容并返回一个对象数组.每个对象都有img标签的src和与图像一起的blob.如果您只想要内嵌图像,则可以选择忽略任何不以"cid"开头的内容.

getBlobFromMessage函数将获取消息的原始内容和img标记的src(包括'cid')并返回关联的blob.

你可以看到这里评论的代码.

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);
}
Run Code Online (Sandbox Code Playgroud)