2013-05-28 38 views
5

Gmail getAttachments nhắn chức năng không trả inlineImages - xem vấn đề 2810 https://code.google.com/p/google-apps-script-issues/issues/detail?id=2810Parsing inlineImages từ nội dung thô Gmail

tôi cần phải làm điều đó, vì vậy tôi đã viết đoạn code dưới đây để phân tích hình ảnh trong dòng ở định dạng blob ra của thông điệp nội dung thô, biết trước hình ảnh cid trong tin nhắn.

Tuy nhiên, tôi sợ phân tích cú pháp này khá dễ vỡ theo cách tôi tìm thấy ký tự đầu tiên và cuối cùng trong nội dung hình ảnh base64, phải không?

Có cách nào tốt hơn để thực hiện việc này không?

Kính trọng, 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 

Trả lời

6

Tôi đã có vấn đề này một số lần, và tôi nghĩ rằng tôi có một giải pháp hợp khá chung. Bắt hình ảnh không được nhúng cũng là một vấn đề.

Tôi không chắc phân tích cú pháp của mình kém dễ vỡ hơn bạn hay không. Cuối cùng, tôi đang hút một phần của multipart bằng cách lấy các đường xung quanh bắt đầu bằng '--'. Mọi thứ khác chỉ là đảm bảo rằng tôi có thể sử dụng điều này mà không sửa đổi mã quá nhiều khi tôi cần nó tiếp theo. Tôi đã có một số email mà không có vẻ theo các \r\n và gây ra vấn đề: một cái gì đó để lookout cho.

Chức năng getInlineImages sẽ lấy nội dung thô của thư và trả về một mảng đối tượng. Mỗi đối tượng sẽ có src của thẻ img và blob đi kèm với hình ảnh. Nếu bạn chỉ muốn hình ảnh nội dòng, bạn có thể chọn bỏ qua bất kỳ thứ gì không bắt đầu bằng 'cid'.

Hàm getBlobFromMessage sẽ lấy nội dung thô của thư và src của thẻ img (bao gồm cả 'cid') và trả lại đốm màu liên quan.

Bạn có thể xem mã đã nhận xét 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); 
} 
+0

Điều này có thể được tăng cường hơn nữa để sử dụng ranh giới nhiều phần thay vì chỉ kiểm tra '-' ở đầu dòng. – fooby

Các vấn đề liên quan