This SO link gives two techniques - using data URIs and using a helper function to fetch the image from some storage location.
Edit: My initial implementation was using the simpler data URI method. Later, also implemented using the other method.
Intially,
// to prevent images from being dropped due to timeouts, we'll encode them inline // https://ads-developers.googleblog.com/2013/11/how-to-send-pdf-reports-with-adwords.html // to parse the img src, we'll use regex, since the html is of limited scope // https://stackoverflow.com/questions/14939296/extract-image-src-from-a-string/15013465 // https://support.google.com/a/answer/1346938 var m; imageurls = []; regexstring = '(http\\S*' + currentTicket +')'; // the \ is escaped, so it becomes doubled. //Logger.log(regexstring); //myregex = new RegExp(/(http\S*0d0a226a47229313863)/,"gi"); // the ticket is the string after S* myregex = new RegExp(regexstring, "gi"); var imageindex=1; while ( m = myregex.exec( contentdata ) ) { imageurls.push( m[1] ); //Logger.log(m[1]) var imagemimetypeandenc = 'data:image/png;base64,'; // default if ( m[1].includes('.jpg?ticket') || m[1].includes('.jpeg?ticket') ) { imagemimetypeandenc = 'data:image/jpeg;base64,'; } else if ( m[1].includes('.gif?ticket') || m[1].includes('.GIF?ticket') ) { imagemimetypeandenc = 'data:image/gif;base64,'; } else if ( m[1].includes('.tif?ticket') || m[1].includes('.tiff?ticket') ) { imagemimetypeandenc = 'data:image/tiff;base64,'; } Logger.log('%s of assetid %s',imageindex.toString(),data_array[i][0].toString()); imageindex = imageindex + 1; var imageBlob = UrlFetchApp.fetch(m[1]).getBlob(); var base64EncodedBytes = Utilities.base64Encode(imageBlob.getBytes()); var imageencoded = imagemimetypeandenc + base64EncodedBytes; contentdata = contentdata.replace(m[1], imageencoded); }
and later, when images were available on Google Drive,
var placeholder = 'data:image/png;base64,iVBORs_a_few_kb_of_chars_QAAAABJRU5ErkJggg=='; // made with https://www.w3docs.com/tools/image-base64
.....
var m; imageurls = []; regexstring = 'img\\s*src\\s*=\\s*"(http\\S*)"'; // the \ is escaped, so it becomes doubled. // Only the http part is captured, within parenthesis // currently it matches only if the img src is within double quotes. "https://whatever" //Logger.log(regexstring); myregex = new RegExp(regexstring, "gi"); var imageindex=1; while ( m = myregex.exec( contentdata ) ) { imageurls.push( m[1] ); Logger.log('%s of assetid %s',imageindex.toString(),data_array[i][0].toString()); imageindex = imageindex + 1; // here we use a helper if the url contains the alfresco url var response; if (m[1].includes('ticket=') ) { //use the helper function after extracting the filename Logger.log('Downloading %s using Alfresco helper', m[1]) var fname = m[1].split('/')[9]; // from the url similar to // https://www.ourdomain.tld/alfresco/d/direct/workspace/NameOfStore/f8b56b7c-long-id-a35c30be756a/filename-15092020100930PM?ticket=fname = fname.split('?')[0]; // handle cases where fname does not have extension var urlFromHelper = UrlFetchApp.fetch(returnUrl+encodeURIComponent(fname)); response = UrlFetchApp.fetch(urlFromHelper, { muteHttpExceptions: true }); } if (response.getResponseCode()==200) { var imageBlob = response.getBlob(); var base64EncodedBytes = Utilities.base64Encode(imageBlob.getBytes()); //var ctype = response.getHeaders().Content-Type var headermap = new Map(Object.entries(response.getHeaders())); var mimetypeofim = headermap.get('Content-Type'); var imagemimetypeandenc = 'data:'+mimetypeofim+';base64,'; var imageencoded = imagemimetypeandenc + base64EncodedBytes; contentdata = contentdata.replace(m[1], placeholder); }
And in cases where we did not want the images to be base64 encoded - for example in the case of large images, which would cause the function to run out of memory - the whole code-block above would be not needed, since the img src link in the original html would work OK.
No comments:
Post a Comment