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);
}
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)