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 )
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 ?
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.
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,"");
}
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 :
EDIT : et ça me creer dans ma boite mail un libellé "done" avec le mail traité :D
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
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 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