'How to extract an attachment from an email to a shared drive that is in a google sheets?

currently I have a google script that runs every x times on my Gmail which retrieves all attachments according to of the label. I enter the email addresses and the path of the folder via a getFolderByName in a google sheets but the problem is that this does not work if the folder is on a shared drive.

I saw different topic on the forum so I know I need to use Drive API

So I would like to retrieve the id of my folder which is in my google sheet instead of my getFolderByName.

Here are the 3 functions:

  • getLibelleConfigs : Retrieves LibelleConfig objects from the configuration sheet
  • getFolderFromPath : Get or create a folder from its path
  • getOrCreateFolder : Recover or create a folder
function getLibelleConfigs() {
    let spreadSheet = getOrCreateSpreadSheet(config.configSheetPath, config.configSheetHeader);

    let sheet = spreadSheet.getSheets()[0];

    let values = sheet.getDataRange().getValues();

    if (values.length == 0 || values.length == 1 && values[0].length == 1 && values[0][0] == "") sheet.appendRow(config.configSheetHeader);

    return values
        .filter((row, i) => {
            return i > 0 && row.length > 0 && row[0] != "";
        })
        .map(row => {
            let libelle = row[0].trim();
            let folderPath = (row.length>1 && row[1] != "" ? row[1] : `/${row[0]}`);
            if (!folderPath.startsWith('/')) folderPath = '/' + folderPath;
            folderPath = folderPath.trim();
            return {
                libelle: libelle,
                folderPath: folderPath
            }
        });
}
function getFolderFromPath(path)
{
    let strings = path.split("/");

    let currentFolder = DriveApp.getRootFolder();

    strings.forEach((string, index) => {
        if (string == "") return;
        currentFolder = getOrCreateFolder(string, currentFolder);
    });

    return currentFolder;
}
function getOrCreateFolder(folderName, parentFolder) {
    
    let folders = parentFolder.getFoldersByName(folderName);
    //Logger.log("folder : " + folders + ", folderName : " + folderName);
    if (folders.hasNext()) {
        return folders.next();
    }
    else {
        return parentFolder.createFolder(folderName);
    
  }
}

google sheets :

+----------------+-----------+
|     LABEL      | ID FOLDER |
+----------------+-----------+
| [email protected] | xxxxx_1   |
| [email protected] | xxxxx_3   |
| [email protected] | xxxxx_1   |
| [email protected] | xxxxx_2   |
+----------------+-----------+

Edit

function saveAttachmentsFromLibelleConfig(libelleConfig, messageIdHistory)
{
    let threads = GmailApp.search(`in:inbox has:attachment label:${libelleConfig.libelle}`);
    console.info(`${threads.length} ${threads.length > 1 ? 'threads trouvés' : 'thread trouvé'} pour le libellé '${libelleConfig.libelle}'`);
    
    if (threads.length == 0) return;

    let parentFolder = getFolderFromPath(libelleConfig.folderPath);

    threads.forEach(thread => {
        try
        {
            thread.getMessages().forEach(message => {
                if (messageIdHistory.includes(message.getId())) return;
                message.getAttachments().forEach(attachment => {
                    console.info(`Enregistrement de la pièces jointe '${attachment.getName()}' du mail '${message.getSubject()}' - '${message.getId()}' envoyé par '${message.getFrom()}' ayant le libellé '${libelleConfig.libelle}'`);
                    parentFolder.createFile(attachment.copyBlob());
                    appendHistory(message.getId(), libelleConfig.libelle, message.getFrom(), attachment.getName(), libelleConfig.folderPath);
                });
                message.markRead();
            });
            thread.moveToArchive();
        }
        catch (e)
        {
            console.warn(`Erreur lors du traitement du thread '${thread.getFirstMessageSubject()}' : ${e}`);
        }
    });
}

My Solution :

 function movefileToSharedDrive() {
  makeCopy("My Drive ID", "To Shared Drive ID");
  deleteFiles("My Drive ID");
}

function makeCopy(srcFolderId, dstFolderId) {
  var srcFolder = DriveApp.getFolderById(srcFolderId);
  var dstFolder = DriveApp.getFolderById(dstFolderId);
  var files = srcFolder.getFiles();
  while (files.hasNext()) {
    var file = files.next();
    var f = file.makeCopy(dstFolder);
    if (file.getMimeType() == MimeType.GOOGLE_APPS_SCRIPT) {
      Drive.Files.update({"parents": [{"id": dstFolderId}]}, f.getId());
    }
  }
}

function deleteFiles(folderId){
  var folder = DriveApp.getFolderById(folderId);
  var files = folder.getFiles()
  while(files.hasNext()){
    files.next().setTrashed(true)
  }
}

There are three steps:

  1. trigger that extracts attachments to my drive
  2. then function makeCopy to drive shared
  3. and finally one that deletes files from my drive(to avoid duplicates)


Solution 1:[1]

You can use Drive.Files.Insert of the Advanced Drive Service to directly insert the file into the shared Drive:

function saveToSharedDrive(sharedDriveId, fileBlob) {  
  const options ={
    supportsAllDrives: true
  }

  var resource = {
    title: fileBlob.getName(),
    mimeType: fileBlob.getContentType(),
    parents:[{
      "id": sharedDriveId
    }]
  }  
  Drive.Files.insert(resource, fileBlob, options)
}

Where sharedDriveId is the ID taken from your Sheet and fileBlob a GmailAttachment object given as an array by:

GmailApp.getMessageById("message-id").getAttachments()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 I hope this is helpful to you