Wednesday, 8 January 2025

How AI helped me automate downloading attachments in GMail

So today I wanted to download my entire history of municipality statements and use some AI tools to build some analytical dashboards for insights. The first thing to automate was downloading attachments from GMail. Instead of manually downloading one-by-one, or manually using a filter rule on GMail, I wanted to test ChatGPT and Gemini to see if it could provide a Google Workspace Appscript to meet my needs.

So Gemini was OKAY - I'm using Gemini Advanced 1.5 Pro with Advanced research. Interesting, it took the prompt "Help me with a google script or query in gmail that I can use for finding all emails from a specified email sender, downloading the attachments from each email, to a specified folder". Gemini then went along with doing the research, then provided the code. Unfortunately, the code didn't work, even after a few tries - maybe it was a Google drive sync issue - but Gemini was stuck on maintaining its response on the nature of the exception ("either an auth issue" or "folder does not exist"). 

So I resorted to ChatGPT 4-Turbo, created a project with these instructions, and used the same prompt and included the original code from Gemini "Act as an expert software engineer to build a google appscript for downloading attachments for all emails from a specific sender. The script needs to work flawlessly from within the Google Apps Script console. I wrote the following code - but the script does not work. I'm getting an Exception: Unexpected error while getting the method or property getFolderById on object DriveApp"

Guess what? ChatGPT nailed it on first try, even added enough logging for tracing! Here's the code. Read the report from Gemini, as this is an example of how content can be generated by AI, and it's only going to get better.

function downloadAttachmentsFromSender() {
// Replace with the email address of the sender.
var senderEmail = '[enter email here]';

// Replace with the ID or intended name of the folder in Google Drive.
var folderName = '[name of folder]'; // Base name for the folder

// Variable to store the target folder
var folder;

try {
// Verify Drive API is working
DriveApp.getFolders();
} catch (e) {
Logger.log("Please authorize the script to access your Drive.");
return; // Exit if Drive access is not authorized
}

// Check if the folder exists
var folders = DriveApp.getFoldersByName(folderName);
if (folders.hasNext()) {
folder = folders.next();
Logger.log("Using existing folder: " + folder.getName());
} else {
// Create a new folder with the current date appended
var dateSuffix = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), 'yyyy-MM-dd');
var newFolderName = folderName + "_" + dateSuffix;
folder = DriveApp.createFolder(newFolderName);
Logger.log("Created new folder: " + newFolderName);
}

// Search for emails from the specified sender.
var threads;
try {
threads = GmailApp.search('from:' + senderEmail);
Logger.log("Found " + threads.length + " threads from sender: " + senderEmail);
} catch (e) {
Logger.log("Error searching for emails: " + e.message);
return; // Exit if Gmail search fails
}

// Iterate through each email thread.
threads.forEach(function (thread) {
var messages = thread.getMessages();

messages.forEach(function (message) {
var attachments = message.getAttachments();

attachments.forEach(function (attachment) {
// Extract the original file extension
var fileName = attachment.getName();
var fileExtension = fileName.substring(fileName.lastIndexOf("."));

// Create the new filename with timestamp and original extension
var newFileName = fileName.substring(0, fileName.lastIndexOf(".")) +
"_" + new Date().getTime() + fileExtension;

try {
folder.createFile(attachment).setName(newFileName);
Logger.log("Saved attachment: " + newFileName);
} catch (e) {
Logger.log("Error saving attachment: " + e.message);
}
});
});
});

Logger.log("Process complete.");
}

Anyway, I now have a repeatable way to extract attachments from emails in GMail, and now you can too.

Below is the auto-generated report from Gemini (excluding the screenshot)

Automating Gmail Attachment Downloads with Google Apps Script

In today's digital age, email remains a primary mode of communication, often carrying crucial documents and files as attachments. Manually sifting through emails and downloading these attachments can be a tedious and time-consuming task. Fortunately, with the power of Google Apps Script, you can automate this process and streamline your workflow. This article provides a comprehensive guide to creating a Google Apps Script that automatically finds emails from a specific sender, downloads their attachments, and saves them to a designated folder in Google Drive.

Understanding Google Apps Script

Google Apps Script is a cloud-based scripting language that allows you to automate tasks and add functionality to Google Workspace applications like Gmail, Google Drive, and Google Sheets. It's based on JavaScript and provides a simple yet powerful way to interact with these applications programmatically1.

To use Google Apps Script with Gmail, you'll need to create a new script project. Here's how:

  1. Go to script.google.com/create.

  2. This will open a new script project in the Apps Script editor.

Next, you'll need to enable the Gmail API. This API gives the script permission to access your Gmail account, allowing it to search for emails, read messages, and download attachments1.

To enable the Gmail API:

  1. In the Apps Script editor, click Editor (</> icon) then code.gs.

  2. Next to Services, click Add a service (+ icon).

  3. Select Gmail API and click Add.



(Add a screenshot here illustrating the process of creating a script and enabling the Gmail API)

Searching for Emails by Sender

The Gmail API provides a robust search functionality that allows you to find emails based on various criteria, including the sender's address. You can use the GmailApp.search() method in your Google Apps Script to search for emails from a specific sender2.

Here's an example of how to use the GmailApp.search() method to find all emails from sender@example.com:


JavaScript



// Search for all emails from the specified sender.
var threads = GmailApp.search('from:sender@example.com');

This code snippet will retrieve all email threads from the specified sender. You can further refine your search by adding more criteria to the query, such as date ranges or keywords in the subject line. For example, to search for emails from sender@example.com with the subject "Project Update," you would use the following query: 2


JavaScript



var threads = GmailApp.search('from:sender@example.com subject:Project Update');

The Gmail API supports a wide range of advanced search operators that allow you to create complex queries to filter emails3. You can also use labels to categorize emails and filter them in your search queries. For example, to search for emails from sender@example.com that have the label "Important," you would use the following query: 3


JavaScript



var threads = GmailApp.search('from:sender@example.com label:Important');

Downloading Attachments

Once you've identified the emails from the desired sender, you can use the getMessages() method to retrieve the messages within each thread and then the getAttachments() method to retrieve the attachments from each message. The getAttachments() method returns an array of GmailAttachment objects, which you can then process to download the attachments4.

Here's an example of how to download attachments from a Gmail thread:


JavaScript



// Search for all emails from the specified sender.
var threads = GmailApp.search('from:sender@example.com');

// Iterate through each email thread.
for (var i = 0; i < threads.length; i++) {
  // Get all the messages in the current thread.
  var messages = threads.getMessages();

  // Iterate through each message in the thread.
  for (var j = 0; j < messages.length; j++) {
    // Get all the attachments for the current message.
    var attachments = messages.getAttachments();

    // Iterate through each attachment in the message.
    for (var k = 0; k < attachments.length; k++) {
      // Save the attachment to Google Drive (more on this in the next section).
      DriveApp.createFile(attachments);
    }
  }
}

This code snippet iterates through each email thread, retrieves the messages within the thread, and then downloads all attachments associated with each message4.

When downloading attachments, it's important to consider potential filename conflicts. If multiple emails have attachments with the same name, the script might overwrite existing files. To avoid this, you can rename files with timestamps or unique identifiers5. For example, you could add a timestamp to the filename like this:


JavaScript



var fileName = attachments.getName() + "_" + new Date().getTime();
DriveApp.createFile(attachments).setName(fileName);

This will ensure that each downloaded attachment has a unique filename.

Saving Attachments to a Specific Folder

To save the downloaded attachments to a specific folder in Google Drive, you can use the DriveApp service in Google Apps Script. You'll need to obtain the folder ID of the destination folder and use the createFile() method to save the attachments to that folder6.

You can find the folder ID in the URL of the folder in Google Drive.

Here's an example of how to save attachments to a specific folder:


JavaScript



// Replace with the ID of the folder in Google Drive.
var folderId = 'your_folder_id';

// Get the folder in Google Drive.
var folder = DriveApp.getFolderById(folderId);

// Search for all emails from the specified sender.
var threads = GmailApp.search('from:sender@example.com');

// Iterate through each email thread.
for (var i = 0; i < threads.length; i++) {
  // Get all the messages in the current thread.
  var messages = threads.getMessages();

  // Iterate through each message in the thread.
  for (var j = 0; j < messages.length; j++) {
    // Get all the attachments for the current message.
    var attachments = messages.getAttachments();

    // Iterate through each attachment in the message.
    for (var k = 0; k < attachments.length; k++) {
      // Save the attachment to the specified folder.
      folder.createFile(attachments);
    }
  }
}

This code snippet retrieves the folder with the specified ID and then saves all downloaded attachments to that folder6.

The DriveApp service also allows you to create new folders and organize attachments within folders7. For example, you could create a new folder for each sender and save their attachments in their respective folders.

Complete Google Apps Script

Here's the complete Google Apps Script that combines all the steps mentioned above:


JavaScript



function downloadAttachmentsFromSender() {
  // Replace with the email address of the sender.
  var senderEmail = 'sender@example.com';

  // Replace with the ID of the folder in Google Drive.
  var folderId = 'your_folder_id';

  // Get the folder in Google Drive.
  var folder = DriveApp.getFolderById(folderId);

  // Search for emails from the specified sender.
  var threads = GmailApp.search('from:' + senderEmail);

  // Iterate through each email thread.
  for (var i = 0; i < threads.length; i++) {
    var messages = threads.getMessages();

    // Iterate through each message in the thread.
    for (var j = 0; j < messages.length; j++) {
      var attachments = messages.getAttachments();

      // Iterate through each attachment in the message.
      for (var k = 0; k < attachments.length; k++) {
        // Add a timestamp to the filename to avoid overwriting existing files.
        var fileName = attachments.getName() + "_" + new Date().getTime();

        // Save the attachment to the specified folder.
        folder.createFile(attachments).setName(fileName);
      }
    }
  }
}

This script will automatically download all attachments from emails sent by the specified sender and save them to the designated folder in Google Drive, with unique filenames to prevent overwriting.

Scheduling the Script

To automate the process completely, you can set up a time-driven trigger in Google Apps Script. This trigger will execute the script at specified intervals, ensuring that attachments are downloaded regularly without manual intervention8.

To create a time-driven trigger:

  1. Open the Google Apps Script editor.

  2. Click on the "Triggers" icon (clock icon) in the left sidebar.

  3. Click on Add Trigger in the bottom right corner.

  4. Configure the trigger settings:

  • Choose which function to run (downloadAttachmentsFromSender in this case).

  • Select "Time-driven" as the event source.

  • Choose a trigger type (e.g., "Hour timer" to run the script every hour).

  • Set the interval for the trigger (e.g., every hour, every day).

  1. Save the trigger.


Once the trigger is set up, the script will run automatically at the specified intervals, downloading attachments from new emails.

Alternative Approaches

While this article focuses on using Google Apps Script to automate Gmail attachment downloads, it's worth noting that alternative approaches exist. You can also use the Gmail API with other programming languages like Python to achieve similar results9. This might be preferable if you're already familiar with Python or need to integrate this functionality into a larger Python application.

Here are some resources for exploring the Gmail API with Python:

  • How to read emails from Gmail using Gmail API in Python: 9

  • Download attachments from Gmail using Gmail API: 10

Conclusion

By leveraging the power of Google Apps Script and the Gmail API, you can automate the tedious task of downloading email attachments. This not only saves time and effort but also ensures that important files are organized and readily accessible in your Google Drive8. This approach offers several benefits:

  • Increased efficiency: Automating the download process eliminates the need for manual intervention, freeing up your time for other tasks.

  • Reduced manual effort: You no longer have to spend time searching for emails and downloading attachments individually.

  • Improved organization: Attachments are automatically saved to a designated folder, making it easy to find and manage them.

The script provided in this article can be easily customized to fit your specific needs, allowing you to filter emails based on different criteria and save attachments to various locations. However, it's important to be aware of potential limitations, such as API quotas and the need for error handling to address issues like filename conflicts or network connectivity problems.

This approach can be particularly useful for individuals who regularly receive emails with attachments, such as those working with invoices, reports, or project files. By automating the download process, you can ensure that these files are readily available when needed, without the hassle of manual downloads.

Works cited

1. Google Apps Script quickstart | Gmail, accessed on January 8, 2025, https://developers.google.com/gmail/api/quickstart/apps-script

2. Gmail Search with Google Apps Script - Digital Inspiration - Labnol.org, accessed on January 8, 2025, https://www.labnol.org/code/19180-gmail-search-with-google-apps-script

3. Searching for Messages | Gmail - Google for Developers, accessed on January 8, 2025, https://developers.google.com/gmail/api/guides/filtering

4. using Google Script to get attachment from Gmail - Stack Overflow, accessed on January 8, 2025, https://stackoverflow.com/questions/46492616/using-google-script-to-get-attachment-from-gmail

5. Google Apps Script to save Gmail attachments to Google Drive of only specific file types, accessed on January 8, 2025, https://stackoverflow.com/questions/75319786/google-apps-script-to-save-gmail-attachments-to-google-drive-of-only-specific-fi

6. Download attachments from GMAIL in bulk. | by Awadesh Madhogaria - Medium, accessed on January 8, 2025, https://medium.com/@toawadh/download-attachments-from-gmail-in-bulk-9caeb6900928

7. Fetch Gmail Attachment to Google Drive using Google Apps Script, accessed on January 8, 2025, https://www.googleappsscript.org/home/fetch-gmail-attachment-to-google-drive-using-google-apps-script

8. Organize Your Gmail Inbox with Google Apps Script - Oktana, accessed on January 8, 2025, https://oktana.com/organize-your-gmail-inbox-with-google-apps-script/

9. How to read Emails from Gmail using Gmail API in Python ? - GeeksforGeeks, accessed on January 8, 2025, https://www.geeksforgeeks.org/how-to-read-emails-from-gmail-using-gmail-api-in-python/

10. Download google drive attachments of an email using Gmail API in python - Stack Overflow, accessed on January 8, 2025, https://stackoverflow.com/questions/68647187/download-google-drive-attachments-of-an-email-using-gmail-api-in-python

11. Automatically Save Email Attachments to Google Drive Using Google Apps Script - Medium, accessed on January 8, 2025, https://medium.com/@pablopallocchi/automatically-save-email-attachments-to-google-drive-using-google-apps-script-7a751a5d3ac9


No comments:

Post a Comment