Extraire des information d'un mail depuis Gmail vers Sheets ?

Bonjour !

est-il possible de faire communiquer un Spreadsheet avec Gmail ?

je reçois toujours ce type de mail filtrer dans un dossier prévu a cette effet ( toujours la même adresse d'envoie, le même objet, et la même conception )

order

Je peux récupérer des éléments dans google Sheets ? ou c'est pas évident.

Merci ! et bonne journée / soirée !

Bonjour,

houlà, cela fait un moment que je n'ai pas plongé là-dedans ... en 2014 je pense et à cette époque je n'utilisais pas GSheets, seulement gmail et calendrier

je crois que cela va être une belle aventure !

quels sont les mails à traiter ? il peut être intéressant de filtrer d'abord dans gmail les messages pertinents et les stocker sous un "label" ... je vais rechercher un lointain message - edit : le voici https://forum.excel-pratique.com/dev/google-apps-script-en-javascript-ou-vba-136936/3#p842771 (il traite essentiellement pour toi de la partie filtre)

je vais regarder ton topic, en attendant, effectivement j'ai filtré ces mails dans un sous dossier dans ma boîte mail 😉

Bon, cela semble plus facile que prévu ... voici un script qui récupère le contenu des mails non lus (c'est un exemple).

var requete = "label:inbox is:unread to:me";
var feuille = SpreadsheetApp.getActiveSheet()

function capturerEmails() {
  var emails = [];
  var threads = GmailApp.search(requete);
  for (var i in threads) {
    var msgs = threads[i].getMessages();
    for (var j in msgs) {emails.push([msgs[j].getDate(),msgs[j].getSubject(),stripTags(msgs[j].getBody())]);}
  }
  if (emails) {feuille.getRange(feuille.getLastRow() + 1, 1, emails.length, emails[0].length).setValues(emails);}
}

function stripTags(body) {
  var regex = /(<([^>]+)>)/ig;
  return body.replace(regex,"");
}

Une fois lus, il faudrait leur affecter un label automatiquement pour éviter les répétitions.

Et il faudrait extraire les informations pertinentes du corps du mail ... peux-tu faire une copie du code source du mail (en effaçant si besoin les données confidentielles) de façon à pouvoir ensuite parser les lignes du tableau ?

je t'envoie le mail en Mp :)

Une fois lus, il faudrait leur affecter un label automatiquement pour éviter les répétitions.

j'ai deja un label pour ces mails, il faut en rajouter un quand ils sont ouvert ? je ne savais pas que c'etait possible :D

Parfait !

Et cela tombe bien, je venais de faire ici https://stackoverflow.com/questions/67790221/replacing-importhtml-with-urlfetchapp/67807779#67807779 un script pour importer une table html

function importTableHTML(url) {
  var html = '<table' + UrlFetchApp.fetch(url).getContentText().match(/(?<=\<table).*(?=\<\/table)/g) + '</table>';
  var trs = [...html.matchAll(/<tr[\s\S\w]+?<\/tr>/g)];
  var data = [];
  for (var i=0;i<trs.length;i++){
    var tds = [...trs[i][0].matchAll(/<(td|th)[\s\S\w]+?<\/(td|th)>/g)];
    var prov = [];
    for (var j=0;j<tds.length;j++){
      donnee=tds[j][0].match(/(?<=\>).*(?=\<\/)/g)[0].replace(/ /g,' ');
      if(donnee.indexOf("</a>")>-1){
        prov.push(donnee.match(/(?<=\>).*(?=\<\/)/g)[0]);
      }else{
        prov.push(donnee);
      }
    }
    data.push(prov);
  }
  return(data);
}

il suffit que je prenne la sixième table du contenu du mail.

du coup j'ai quelque chose a modifier sur ce script ?

oui, il ne faut pas le prendre en l'état ... je regarde pour adapter

pas très simple mis on y arrive mieux que ce que je craignais ... il faut pour toi régler la requête en y mettant le label que tu as créé

var requete = "label:xxxxxxxxxxxxx to:me NOT label:done";

on pourra enlever la colonne C si c'est ok

var requete = "label:inbox is:unread to:me NOT label:done";
var feuille = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('mails')
var exemple = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('code source exemple').getRange('A1').getValue()

function capturerEmails() {
  let label = GmailApp.getUserLabelByName("done");
  if (!label) {label = GmailApp.createLabel("done")}
  //feuille.getRange('A2:Z'+(feuille.getLastRow()+1)).clearContent()
  var threads = GmailApp.search(requete);
  threads.forEach(thread => {
    var msgs = thread.getMessages();
    for (var j in msgs) {
      var r = feuille.getLastRow()+1
      var data = [] 
      var prov = []
      var msg = msgs[j].getBody().replace(/\n/g,'')
      msg = exemple
      prov.push(msgs[j].getDate()) 
      prov.push(msgs[j].getSubject()) 
      prov.push(msg) 
      data.push(prov)
      feuille.getRange(r,1,1,3).setValues(data);
      feuille.getRange(r,4,1,2).setValues(importOrder(msg));
      var a = (importTableHTML(msg))
      feuille.getRange(r,6,a.length,a[0].length).setValues(a);
    }
    label.addToThread(thread);
  })
}

function importOrder(body) {
  var source = body.replace(/\n/g,'')
  var data = [];
  var defaut = 'no—no'
  try{
    var entete = (source.match(/(?<=\<h2.*\>).*(?=\<\/h2\>)/g)[0]).replace(/\s/g, "").split('—')
  }
  catch(e){
     var entete = defaut.split('—')
  }
  data.push(entete)
  return(data);
}

function importTableHTML(body) {
  var source = body.replace(/\n/g,'')
  var data = [];
  var defaut = 'no—no—no'
  try{
    var html = '<table>' + source.match(/(?<=\<tbody\>).*(?=\<\/tbody\>)/g)[0] + '<table>'
    var trs = [...html.matchAll(/<tr[\s\S\w]+?<\/tr>/g)];
    for (var i=0;i<trs.length;i++){
      var tds = [...trs[i][0].matchAll(/<(td|th)[\s\S\w]+?<\/(td|th)>/g)];
      var prov = [];
      for (var j=0;j<tds.length;j++){
        donnee=tds[j][0].match(/(?<=\>).*(?=\<\/)/g)[0].replace(/ /g,' ');
        if (j>0){donnee = donnee.replace(/\s/g, "")}
        prov.push(stripTags(donnee))
      }
      data.push(prov);
    }
  }
  catch(e){
    data.push(defaut.split('—'))
  }
  return(data);
}

function stripTags(body) {
  var regex = /(<([^>]+)>)/ig;
  return body.replace(regex,"");
}

je fais un essai tout à l'heure et je te donne un retour

merci encore !!

TypeError: Cannot read property 'getRange' of null
(anonyme)    @ capturerEmails.gs:3

Voici le retour que j'ai

PS : J'ai bien mis le label comme ceci, si c'est bien comme ça

var requete = "label:realt-commandes is:unread to:me NOT label:done";

enlève is:unread et essaye au moins une fois

de toute façon, il faut que je traite le cas où il n'y a rien donc ...

meme chose.

En revanche, fait intéressant ( pour moi en tout cas )

lorsque je modifie :

var exemple = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('code source exemple').getRange('A1').getValue()

par :

var exemple = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('mails').getRange('A1').getValue()

(donc en changeant le 'code source exemple' par 'mails' )

il y a bien communication, j'ai ce retour :

capture

EDIT : et ça me creer dans ma boite mail un libellé "done" avec le mail traité :D

enlève is:unread et essaye au moins une fois

et si je laisse ma modification ( msg au dessus ) , je retrouve le listing de tout les mails contenue dans mon libellé

capture

donc je pense que le probleme c'est bien "code source exemple"

ben oui, il n'y a aucun code source dans la colonne C !!

enlève

msg = exemple

j'ai enlevé le "msg = exemple " de la ligne 17,

petit changement

capture



EDIT, j'ai trouvé un lien concernant un sujet similaire ( il me semble (?)) je ne comprend pas tout les éléments ) Site

Pourrais-tu me donner en mp le contenu d'une cellule de la colonne C ?

Note que pour tester, soit tu supprimes le libellé "done" dans ta boite mail (cela n'efface pas les messages), soit tu enlèves provisoirement label.addToThread(thread);

Comme je n'ai pas accès aux mails, j'avais copié l'exemple du code source -d'où le msg=exemple- dans le contenu de C et cela me donnait bien ce que je cherchais. Donc le problème, c'est le contenu exacte de C.

Pour ce qui est du lien, je ne pense pas qu'il soit utile car on a bien ici en colonnes A, B, C les éléments des mails. Il s'agit de décortiquer le contenu de C pour accder aux informations du tableau.

je t'ai partagé un sheet, ça devrait le faire

Je clôture le poste, je veux pas trop que tu te casses la tête sur quelque chose de complexe pour un simple "confort de saisie"

je voyais quelque chose de moins complexe du même type qu'un import XML en gros

Merci pour l'intérêt

Rechercher des sujets similaires à "extraire information mail gmail sheets"