Updating Google Doc script to Google Drive (Archiv

2020-07-18 04:01发布

My script saves pdf versions of emails with a specific label to Google drive. I have three nearly identical versions of the script for three different labels and I run them periodically.

Recently they stopped working because of depreciation of DocsList. I changed all the instances of DocsList to DriveApp, but now am getting the error "TypeError: Cannot find function createFolder in object FolderIterator."

The issue is in the last few lines, where the script should be creating a folder in which to save the pdf of the emails.

Could someone help me fix the createFolder function and get the script back up and running?

/**
 * Main function run at spreadsheet opening
 */
function onOpen() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var menuEntries = [ 
    {name: "Initialize", functionName: "init"},
    {name: "Archive Gmail Messages", functionName: "ScanGmail"}
  ];
  ss.addMenu("Gmail Archiver", menuEntries);
}
    
/**
 * Initialize the system
 */
function init() {
    // Create the needed Gmail label
    GmailApp.createLabel("Archive to Drive");
    
    // Create Google Drive folder if doesn't exists
    try {
       var folder = DriveApp.getFolder("Email Archive");
    } catch(e) {
       // Folder doesn't exists
       DriveApp.createFolder("Email Archive");
    }
    
    Browser.msgBox("Created Gmail label: Archive to Drive and Google Drive folder: Email Archive");
}

/**
 * Scan Gmail account for message archive requests
 */
function ScanGmail() {
  // Default Drive folder where to archive messages
  var baseFolder = "Sparkfly Receipts 2015";
  
  // Get the label
  var label = GmailApp.getUserLabelByName("Sparkfly receipt");
    var threadsArr = getThreadsForLabel(label);
    for(var j=0; j<threadsArr.length; j++) {
      var messagesArr = getMessagesforThread(threadsArr[j]);
      for(var k=0; k<messagesArr.length; k++) {
        var messageId = messagesArr[k].getId();
        var messageDate = Utilities.formatDate(messagesArr[k].getDate(), Session.getTimeZone(), "MM.dd.yyyy");
        var messageFrom = messagesArr[k].getFrom();
        var messageSubject = messagesArr[k].getSubject();
        var messageBody = messagesArr[k].getBody();
        var messageAttachments = messagesArr[k].getAttachments();
        
        // Create the new folder to contain the message
        var newFolderName = messageDate + " - " + messageSubject;
        var newFolder = createDriveFolder(baseFolder, newFolderName);
        
        // Create the message PDF inside the new folder
        var htmlBodyFile = newFolder.createFile('body.html', messageBody, "text/html");
        var pdfBlob = htmlBodyFile.getAs('application/pdf');
        pdfBlob.setName(newFolderName + ".pdf");
        newFolder.createFile(pdfBlob);
        htmlBodyFile.setTrashed(true);
        

        // Save attachments
        for(var i = 0; i < messageAttachments.length; i++) {
            var attachmentName = messageAttachments[i].getName();
            var attachmentContentType = messageAttachments[i].getContentType();
            var attachmentBlob = messageAttachments[i].copyBlob();
            newFolder.createFile(attachmentBlob);
        }

      }
      // Remove Gmail label from archived thread
      label.removeFromThread(threadsArr[j]);
    }
    Browser.msgBox("Gmail messages successfully archived to Google Drive");
}


/**
 * Find all user's Gmail labels that represent mail message
 * movement requests es: moveto->xx@yyyy.com
 *
 * @return {GmailLabel[]} Array of GmailLabel objects
 */
function scanLabels() {
  // logs all of the names of your labels
  var labels = GmailApp.getUserLabels();
  var results = new Array();
  for (var i = 0; i < labels.length; i++) {
    if(labels[i].getName() == "Sparkfly receipt") {
      results.push(labels[i]);
    }
  }
  return results;
}

/**
 * Get all Gmail threads for the specified label
 *
 * @param {GmailLabel} label GmailLabel object to get threads for
 * @return {GmailThread[]} an array of threads marked with this label
 */
function getThreadsForLabel(label) {
  var threads = label.getThreads();
  return threads;
}

/**
 * Get all Gmail messages for the specified Gmail thread
 *
 * @param {GmailThread} thread object to get messages for
 * @return {GmailMessage[]} an array of messages contained in the specified thread
 */
function getMessagesforThread(thread) {
  var messages = thread.getMessages();
  return messages;
}


/**
 * Get methods of an object
 * @param {Object} object to scan
 * @return {Array} object's methods
 */
function getMethods(obj) {
  var result = [];
  for (var id in obj) {
    try {
      if (typeof(obj[id]) == "function") {
        result.push(id + ": " + obj[id].toString());
      }
    } catch (err) {
      result.push(id + ": inaccessible");
    }
  }
  return result;
}

/**
 * Create a Google Drive Folder
 *
 * @param {String} baseFolder name of the base folder
 * @param {String} folderName name of the folder
 * @return {Folder} the folder object created representing the new folder 
 */
function createDriveFolder(baseFolder, folderName) {
  var baseFolderObject = DriveApp.getFoldersByName(baseFolder);
  return baseFolderObject.createFolder(folderName);
}

1条回答
贼婆χ
2楼-- · 2020-07-18 04:53

The method getFoldersByName() returns a FolderIterator (collection of folder objects), and that collections does not contain a "createFolder" method.

So if the collection has at least one Folder object you should take that object out of the collection and then call "createFolder".

Here you can find the documentation: https://developers.google.com/apps-script/reference/drive/folder#getFoldersByName(String)

查看更多
登录 后发表回答