Saving an attachment to Google drive

61 views
Skip to first unread message

Michał Cichocki

unread,
Dec 22, 2022, 6:08:00 AM12/22/22
to Google Apps Script Community
Hello, I have the script below that automatically saves an attachment from an email address to google drive. The problem occurs when an attachment with the given name already exists in Google Drive. Then the file is not saved. How to make a file overwritten (replaced with a new one)?

I suspect the following lines are the most important:
var folder = getOrMakeFolder(path);
  var check = folder.getFilesByName(file);
  if(check.hasNext()) {
    Logger.log(path + '/' + file + ' already exists. File not overwritten.');
    return;
  }
  folder.createFile(attachment).setName(file);
  Logger.log(path + '/' + file + ' saved.');
}

--------------------------------

var GMAIL_LABEL = 'Invoice';
var GDRIVE_FILE = 'documents/$y/rechnungen/$sublabel/$y-$m-$d_$domain_$mc_$ac.$ext';


/* ------------- no changes below needed ------------------------- */

/**
 * Get all the starred threads within our label and process their attachments
 */
function main() {
  var labels = getSubLabels(GMAIL_LABEL);
  for(var i=0; i<labels.length; i++) {
    var threads = getUnprocessedThreads(labels[i]);
    for(j=0; j<threads.length; j++) {
      processThread(threads[j], labels[i]);
    }
  }
}

/**
 * Returns the Google Drive folder object matching the given path
 *
 * Creates the path if it doesn't exist, yet.
 *
 * @param {string} path
 * @return {Folder}
 */
function getOrMakeFolder(path) {
  var folder = DriveApp.getRootFolder();
  var names = path.split('/');
  while(names.length) {
    var name = names.shift();
    if(name === '') continue;
    
    var folders = folder.getFoldersByName(name);
    if(folders.hasNext()) {
      folder = folders.next();
    } else {
      folder = folder.createFolder(name);
    }
  }
  
  return folder;
}

/**
 * Get all the given label and all its sub labels
 *
 * @param {string} name
 * @return {GmailLabel[]}
 */
function getSubLabels(name) {
  var labels = GmailApp.getUserLabels();
  var matches = [];
  for(var i=0; i<labels.length; i++){
    var label = labels[i];
    if(
      label.getName() === name ||
      label.getName().substr(0, name.length+1) === name+'/'
    ) {
      matches.push(label);
    }
  }
  
  return matches;
}

/**
 * Get all starred threads in the given label
 *
 * @param {GmailLabel} label
 * @return {GmailThread[]}
 */
function getUnprocessedThreads(label) {
  var from = 0;
  var perrun = 50; //maximum is 500
  var threads;
  var result = [];
  
  do {
    threads = label.getThreads(from, perrun);
    from += perrun;
    
    for(var i=0; i<threads.length; i++) {
      if(!threads[i].hasStarredMessages()) continue;
      result.push(threads[i]);
    }
  } while (threads.length === perrun);
  
  Logger.log(result.length + ' threads to process in ' + label.getName());
  return result;
}

/**
 * Get the extension of a file
 *
 * @param  {string} name
 * @return {string}
 */
function getExtension(name) {
  var re = /(?:\.([^.]+))?$/;
  var result = re.exec(name);
  if(result && result[1]) {
    return result[1].toLowerCase();
  } else {
    return 'unknown';
  }
}

/**
 * Apply template vars
 *
 * @param {string} filename with template placeholders
 * @param {info} values to fill in
 * @param {string}
 */
function createFilename(filename, info) {
  var keys = Object.keys(info);
  keys.sort(function(a,b) {
    return b.length - a.length;
  });
  
  for(var i=0; i<keys.length; i++) {
    filename = filename.replace(new RegExp('\\$'+keys[i], 'g'), info[keys[i]]);
  }
  return filename;
}

function saveAttachment(attachment, path) {
  var parts = path.split('/');
  var file = parts.pop();
  var path = parts.join('/');
  
  var folder = getOrMakeFolder(path);
  var check = folder.getFilesByName(file);
  if(check.hasNext()) {
    Logger.log(path + '/' + file + ' already exists. File not overwritten.');
    return;
  }
  folder.createFile(attachment).setName(file);
  Logger.log(path + '/' + file + ' saved.');
}

/**
 * @param {GmailThread} thread
 * @param {GmailLabel} label where this thread was found
 */
function processThread(thread, label) {
  var messages = thread.getMessages();
  for(var j=0; j<messages.length; j++) {
    var message = messages[j];
    if(!message.isStarred()) continue;
    Logger.log('processing message from '+message.getDate());
    
    var attachments = message.getAttachments();
    for(var i=0; i<attachments.length; i++) {
      var attachment = attachments[i];
      var info = {
        'name': attachment.getName(),
        'ext': getExtension(attachment.getName()),
        'domain': message.getFrom().split('@')[1].replace(/[^a-zA-Z]+$/,''), // domain part of email
        'sublabel': label.getName().substr(GMAIL_LABEL.length+1),
        'y': ('0000' + (message.getDate().getFullYear())).slice(-4),
        'm': ('00' + (message.getDate().getMonth()+1)).slice(-2),
        'd': ('00' + (message.getDate().getDate())).slice(-2),
        'h': ('00' + (message.getDate().getHours())).slice(-2),
        'i': ('00' + (message.getDate().getMinutes())).slice(-2),
        's': ('00' + (message.getDate().getSeconds())).slice(-2),
        'mc': j,
        'ac': i,
      }
      var file = createFilename(GDRIVE_FILE, info);
      saveAttachment(attachment, file);
    }
    
    message.unstar();
  }
}

Reply all
Reply to author
Forward
0 new messages