google-apps-script - gmailapp - mail app google script
Analizar inlineImages desde contenido sin procesar de Gmail (1)
La función getAttachments del mensaje de Gmail no devuelve inlineImages: consulta el problema 2810 https://code.google.com/p/google-apps-script-issues/issues/detail?id=2810
Tengo que hacer eso, así que escribí el código a continuación para analizar la imagen en línea en formato blob del contenido sin procesar del mensaje, conociendo el cid de la imagen dentro del mensaje, con anticipación.
Sin embargo, me temo que este análisis es bastante frágil en la forma en que encuentro el primer y el último personaje en el contenido de la imagen de base64, ¿no?
¿Hay una mejor manera de hacer esto?
Saludos, 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
He tenido este problema varias veces, y creo que tengo una solución de caso bastante general. Obtener imágenes no incrustadas también ha sido un problema.
No estoy seguro de que mi análisis sea menos frágil que el tuyo. Al final, estoy chupando la parte de la multipart
agarrando las líneas circundantes que comienzan con ''--''
. Todo lo demás es solo asegurarme de poder usar esto sin modificar demasiado el código cuando lo necesite a continuación. He recibido algunos correos electrónicos que no parecen seguir a /r/n
y que causan problemas: algo a lo que hay que prestar atención.
La función getInlineImages
tomará el contenido sin getInlineImages
del mensaje y devolverá una matriz de objetos. Cada objeto tendrá el src de la etiqueta img y el blob que acompaña a la imagen. Si solo quieres imágenes en línea, puedes elegir ignorar cualquier cosa que no comience con ''cid''.
La función getBlobFromMessage
tomará el contenido sin procesar del mensaje y el src de la etiqueta img (incluido ''cid'') y devolverá el blob asociado.
Puedes ver el código comentado aquí .
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);
}