Home > Back-end >  google apps script: get gmail jpg attachments & insert them into google sheets
google apps script: get gmail jpg attachments & insert them into google sheets

Time:01-31

The code finds all the jpg's from a sender and then creates an array with those images and then is supposed to insert the received images into the cells of the sheet.

Instead, the code inserts the word Blog into the cells instead of the images.

I've tried several methods to solve the problem but have not had any luck.

function importEmailsWithJPGs() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var emailAddress = "[email protected]";

  var threads = GmailApp.search("from:"   emailAddress   " filename:jpg");
  var attachments;
  var date;
  
  var rowData = {};
  
  for (var i = 0; i < threads.length; i  ) {
    var messages = threads[i].getMessages();
    for (var j = 0; j < messages.length; j  ) {
      attachments = messages[j].getAttachments();
      date = messages[j].getDate();
      var dateString = Utilities.formatDate(date, "GMT", "yyyy-MM-dd");
      
      if (!rowData[dateString]) {
        rowData[dateString] = [date];
      }
      
      for (var k = 0; k < attachments.length; k  ) {
        if (attachments[k].getContentType().indexOf("image/jpeg") !== -1) {
         
         //var image = attachments[k].getAs('image/jpeg');
         // var imageName = attachments[k].getName();
         // var blob = new Blob([image], { type: 'image/jpeg' });
         // rowData[dateString].push(blob);
          //var image = attachments[k].getAs('image/jpeg');
        
         // var imageName = attachments[k].getName();
         // var byteArray = image.getBytes();
         // var base64EncodedImage = Utilities.base64Encode(byteArray);
         // var blob = Utilities.newBlob(base64EncodedImage, 'image/jpeg', imageName);
         // rowData[dateString].push(blob);

          var image = attachments[k].copyBlob();
          var imageName = attachments[k].getName();
          var blob = Utilities.newBlob(image.getBytes(), 'image/jpeg', imageName);
          rowData[dateString].push(blob);



        }
      }
    }
  }
  
  for (var key in rowData) {
    sheet.appendRow(rowData[key]);
  }
  
  var data = sheet.getDataRange().getValues();
  for (var i = 0; i < data.length; i  ) {
    for (var j = 1; j < data[i].length; j  ) {
      var cell = sheet.getRange(i   1, j   1);
      var value = data[i][j];
       if (value && value.getBytes) {
        //var image = value;
        var image = value.getAs('image/jpeg');

        //var imageData = new Uint8Array(image.getBytes());
        var cellWidth = cell.getWidth();
        var cellHeight = cell.getHeight();
        var imageWidth = image.getWidth();
        var imageHeight = image.getHeight();
        var ratio = Math.min(cellWidth / imageWidth, cellHeight / imageHeight);
        cell.setValue("");
       // cell.setImageData(imageData);
       cell.setImageData(image);
        }      
    }
  }
}

CodePudding user response:

Modification points:

  • First, I think that the reason that the text of Blob is put to the cell is due to that appendRow cannot put the image blob to the cell.

  • After that line of var data = sheet.getDataRange().getValues();, I think that value && value.getBytes is always false. Because, value.getBytes is undefined, and also, there is no method of setImageData in Class Range at cell.setImageData(image);. And, an error occurs at value.getAs('image/jpeg') because value has no method.

Unfortunately, from your reply, I cannot understand the relationship between for (var key in rowData) { sheet.appendRow(rowData[key]); } and the script below var data = sheet.getDataRange().getValues();. But, if you want to just put the image data from the image blob to the cells instead of the text of Blob, how about the following modification?

In this modification, a Google Apps Script library is used. Because in the current stage, unfortunately, the image blob cannot be directly put into a cell. So, I created this library. In order to use the following modified script, please do the following flow.

Usage:

1. Install Google Apps Script library.

You can see how to install it at https://github.com/tanaikech/DocsServiceApp#how-to-install. (Author of this library: me)

2. Enable Drive API.

Please enable Drive API at Advanced Google services.

3. Modified script:

Please modify your script as follows.

From:

for (var key in rowData) {
  sheet.appendRow(rowData[key]);
}

var data = sheet.getDataRange().getValues();
for (var i = 0; i < data.length; i  ) {
  for (var j = 1; j < data[i].length; j  ) {
    var cell = sheet.getRange(i   1, j   1);
    var value = data[i][j];
     if (value && value.getBytes) {
      //var image = value;
      var image = value.getAs('image/jpeg');

      //var imageData = new Uint8Array(image.getBytes());
      var cellWidth = cell.getWidth();
      var cellHeight = cell.getHeight();
      var imageWidth = image.getWidth();
      var imageHeight = image.getHeight();
      var ratio = Math.min(cellWidth / imageWidth, cellHeight / imageHeight);
      cell.setValue("");
     // cell.setImageData(imageData);
     cell.setImageData(image);
      }      
  }
}

To:

var lastRow = sheet.getLastRow();
var v = Object.values(rowData);
var values = v.map(([a]) => [a]);
sheet.getRange(lastRow   1, 1, values.length).setValues(values);
var obj = v.map(([, blob], i) => ({ blob, range: { row: lastRow   i   1, column: 2 } }));
DocsServiceApp.openBySpreadsheetId(sheet.getParent().getId()).getSheetByName(sheet.getSheetName()).insertImage(obj);
  • When this script is run, the text value and the image data are put into the columns "A" and "B", respectively.

Reference:

  • Related