miałem ten problem kilka razy i myślę, że mam dość ogólne rozwiązanie sprawy. Problemem jest także uzyskanie nie osadzonych obrazów.
Nie jestem pewien, czy moje parsowanie jest mniej delikatne niż twoje. W końcu wysysam część multipart
, chwytając otaczające linie zaczynające się od '--'
. Wszystko inne polega na upewnieniu się, że mogę go użyć bez zbytniego modyfikowania kodu, kiedy będę go potrzebować. Otrzymałem kilka e-maili, które nie wyglądają na zgodne z \r\n
i powodują problemy: na co zwrócić uwagę.
Funkcja pobiera surową treść wiadomości i zwraca tablicę obiektów. Każdy obiekt będzie miał src z tagu img i obiektu typu blob związanego z obrazem. Jeśli chcesz tylko obrazy wbudowane, możesz zignorować wszystko, co nie zaczyna się od "cid".
Funkcja getBlobFromMessage
pobiera nieprzetworzoną treść wiadomości i src z tagu img (w tym "cid") i zwraca powiązany obiekt typu blob.
Możesz zobaczyć kod skomentowany here.
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);
}
Można to ulepszyć, aby korzystać z wieloczęściowej granicy, zamiast sprawdzać tylko "-" na początku linii. – fooby