Google Script - Lister Labels de Gmail - - Créer Sauver mails dans Drive

Bonjour,

Pourriez vous m'aider sur deux aspects concernant mon script que je souhaite développer.

1- Réduire le temps d'exécution du script qui fonctionne mais qui est trop long (90 secondes pour 75 labels).

J'ai essayé de faire un array au lieu de appendRow mais cela ne fonctionne pas.

Avez vous une solution?

Voici le script qui fonctionne:

function listOfLabels() {

var ss = SpreadsheetApp.getActiveSpreadsheet(); 
var activeSheet = ss.getSheetByName("List of Gmail labels");

//Loop sur Gmail pour récupérer l'ensemble des labels
var labels = GmailApp.getUserLabels();
  for (var i = 0; i < labels.length; i++) {
  Logger.log("label: " + labels[i].getName());
  activeSheet.appendRow([labels[i].getName()]);
  }

  //Insertion checklist en colonne B
  var lastRow = activeSheet.getLastRow();
  rangeCheckbox = activeSheet.getRange(2,2,lastRow-1);
  checkbox = SpreadsheetApp.newDataValidation()
    .requireCheckbox()
    .setAllowInvalid(false)
    .build();
  rangeCheckbox.setDataValidation(checkbox).setValue(false);

  //Trier colonne A par ordre chronologique
  rangeSort = activeSheet.getRange("A2:A").sort({column: 1, ascending: true});

}

2-Dans un second temps, pourriez vous m'aider à développer la suite, dont les explications sont ci-dessous:

2A- Lorsque un checkBox est en "true", le script se déclenche automatiquement et sauve tous les mails du Label en true et ses enfants, dans mon drive. Un pop-up apparaitra pour que je lui dise dans quel dossier de mon drive je souhaite le sauver.

2B- Je souhaiterais que mes mails et pièces jointes soient sauver en pdf(cela me semble etre le mieux) !

Merci pour votre aide.

Bonne journée

Bonjour,

Sur la partie la plus chronophage, remplace :

  //Loop sur Gmail pour récupérer l'ensemble des labels
  var labels = GmailApp.getUserLabels();
  for (var i = 0; i < labels.length; i++) {
  Logger.log("label: " + labels[i].getName());
  activeSheet.appendRow([labels[i].getName()]);
  }

par

  //Loop sur Gmail pour récupérer l'ensemble des labels
  var labels = GmailApp.getUserLabels();
  var tableau = []
  for (var i = 0; i < labels.length; i++) {
    tableau.push([labels[i].getName()]);
  }
  activeSheet.getRange(2,1,tableau.length,1).setValues(tableau)

tu divises le temps par~5 (cela dépend du nbre de labels sans doute)

Pour caractériser le temps pris par chaque groupe d'instructions, n'hésite pas à faire ceci

var d = new Date()

// ici le groupe d'instructions

Logger.log(new Date() - d)

tu auras le temps du serveur en millisecondes

Pour le point2, on ne va pas réinventer l'eau chaude ... il suffit d'adapter ce code qui fonctionne très bien.

https://www.labnol.org/code/19117-save-gmail-as-pdf

  1. Le code limite aujourd'hui aux 5 derniers mails, mais cela peut se changer ... soit tous, soit en fonction d'une date.
  2. Quel est le nom dossier dans lequel ils seront sauvegardés ? le dossier sera créé automatiquement s'il n'existe pas.

Une proposition pour le point 2

Mets un déclencheur sur la fonction onSpeEdit (lors d'une modification)

Attention, cela peut être très log, il faut aussi à un moment voir comment limiter aux "nouveaux" mails par une date par exemple.

function onSpeEdit(event){
  var feuille = event.source.getActiveSheet();
  var cellule = event.source.getActiveRange();
  if (feuille.getName()=='List of Gmail labels' && cellule.getColumn()==2 && cellule.getValue()){
    saveGmailAsPDF(cellule.offset(0,-1).getValue())
    cellule.setValue(!cellule.getValue())
    SpreadsheetApp.getActive().toast('Sauvegarde effectuée !', 'Fin de script 🗃️')
  }
}

function saveGmailAsPDF(gmailLabels) {

  //var gmailLabels  = "Promotions";
  //var driveFolder  = "Promotions_mails";
  var driveFolder = 'Sauvegarde_'+gmailLabels

  var threads = GmailApp.search("in:" + gmailLabels,0,1);

  if (threads.length > 0) {

    /* Google Drive folder where the Files would be saved */
    var folders = DriveApp.getFoldersByName(driveFolder);
    var folder = folders.hasNext() ?
        folders.next() : DriveApp.createFolder(driveFolder);

    /* Gmail Label that contains the queue */
    var label = GmailApp.getUserLabelByName(gmailLabels) ?
        GmailApp.getUserLabelByName(gmailLabels) : GmailApp.createLabel(driveFolder);

    for (var t=0; t<threads.length; t++) {

      threads[t].removeLabel(label);
      var msgs = threads[t].getMessages();

      var html = "";
      var attachments = [];

      var subject = threads[t].getFirstMessageSubject();

      /* Append all the threads in a message in an HTML document */
      for (var m=0; m<msgs.length; m++) {

        var msg = msgs[m];

        html += "From: " + msg.getFrom() + "<br />";
        html += "To: " + msg.getTo() + "<br />";
        html += "Date: " + msg.getDate() + "<br />";
        html += "Subject: " + msg.getSubject() + "<br />";
        html += "<hr />";
        html += msg.getBody().replace(/<img[^>]*>/g,"");
        html += "<hr />";

        var atts = msg.getAttachments();
        for (var a=0; a<atts.length; a++) {
          attachments.push(atts[a]);
        }
      }

      /* Save the attachment files and create links in the document's footer */
      if (attachments.length > 0) {
        var footer = "<strong>Attachments:</strong><ul>";
        for (var z=0; z<attachments.length; z++) {
          var file = folder.createFile(attachments[z]);
          footer += "<li><a href='" + file.getUrl() + "'>" + file.getName() + "</a></li>";
        }
        html += footer + "</ul>";
      }

      /* Conver the Email Thread into a PDF File */
      var tempFile = DriveApp.createFile("temp.html", html, "text/html");
      folder.createFile(tempFile.getAs("application/pdf")).setName(subject + ".pdf");
      tempFile.setTrashed(true);

    }
  }
}

Bonjour Vincent,

un retour sur la proposition ?

combien as-tu gagné en temps d'exécution ?

Bonjour Mike,

désolé de ne pas t'avoir répondu avant...

Concernant le point 1, le temps d'exécution est beaucoup plus rapide avec la méthode Array (c'est passé de 11 secondes à 0.5 seconde !!!!! ).

Je ne t'avais pas répondu car je bute sur le point deux.

Le transfert de Gmail vers drive en sauvant le mail en pdf, fonctionne.

Mais, j'ai du mal à comprendre pourquoi des fois il me sauve 4 ou 5 mails et des fois il ne m'en sauve qu'un !

Certainement, que d'en le script il y a une temporisation maxi à ne pas dépasser !?

Mes connaissances étant limitées, je n'ai pas trouvé la réponse !

Le sais-tu?

Merci encore pour ton dévouement et ton aide

Vincent

Oui en effet, un script est limité en temps d'exécution (6mn) et cette opération prend du temps.

Il vaut mieux le faire de façon fractionnée, et trouver un moyen justement de ne le faire que pour certains (mes essais étaient limités à moins de 10 mails assez simples!). Il faut peut-être le faire quotidiennement si le nombre de mails n'est pas trop important. Voire du reste à le faire sans les pièces attachées si celles-ci sont déjà enregistrées dans un autre dossier ?

On peut aussi le faire par paquets de 5 par exemple (curieusement j'avais mis 0,1 dans le code ci-dessus !!)

var threads = GmailApp.search("in:" + gmailLabels, 0, 5)

Je crois que Gilbert avait aussi donné un lien sur ce sujet.

Il existe une procédure batchUpdate https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/batchUpdate mais que je ne connais pas bien et je ne suis pas sûr qu'elle puisses ici diminuer le temps d'exécution (car cette procédure ne permet pas d'en augmenter le temps).

Ma conclusion est qu'il faut le faire par paquets compatibles avec la limite de temps + voir s'il faut aussi enregistrer les annexes déjà présentes par ailleurs si c'est le cas.

Merci Mike pour tes conseils et ton aide.

Bonne journée

Rechercher des sujets similaires à "google script lister labels gmail creer sauver mails drive"