Script envoi mail

Bonjour à tous,

je suis vraiment tout nouveau sur google sheet. j'e faisais quelques macros sur Excel mais pas beaucoup,

tout ça pour dire que je suis débutant...

j'ai un fichier google sheet avec des coordonnées extraites d'une base.

Je souhaite avoir un script qui en appuyant sur un bouton :

1/ prépare un seul mail à tous les destinataires (dont l'adresse est pas exemple dans la colonne D4 à D20

2/ créé un objet de l'email avec des valeurs contenues dans plusieurs cellules de ce même fichier. admettons B2 et B3

3/ Ajoute un texte dans le corps de mail "Bonjour, voici le document, ....... j'écrivais ce texte plus tard)

-> je ne veux pas que le mail soir envoyé tout seul, je peux pouvoir le modifier avant de l'envoyer

Merci beaucoup à tous

Bonjour,

Voici une piste : (étape par étape)

1 : on déclare l'environnement de travaille (fichier et feuille sheet)

function sendMail() {
  let ss = SpreadsheetApp.getActiveSpreadsheet();
  let sheet = ss.getActiveSheet();

2 : on déclare la plage des mail et on les stocke dans une variable idem pour l'objet (imaginons la date en B2 et le titre en B3)

  let emails = sheet.getRange('D4:D20').getValues();
  let objectDate = sheet.getRange('B2').getDisplayValue();
  let objectTitle = sheet.getRange('B3').getValue();

3 : maintenant il reste le corps du mail, dans cet exemple je le mets dans le script, mais il est aussi possible de le mettre dans une cellule afin de le modifier + simplement si besoin, dans ce cas il suffit de suivre la logique sheet.getRange(' cellule ici ').getValue()

let body = "Bonjour, voici le document,...";

-> je ne veux pas que le mail soir envoyé tout seul, je peux pouvoir le modifier avant de l'envoyer

J'ignore si tu souhaites vérifier le mail pour chaque mail pour chaque adresse ou bien une seule fois pour le global, je vais considérer cette seconde option :

4 : faire un prompt pour afficher le corps du mail et demander un nouveau corps si nécessaire (il est aussi possible de conserver une partie fixe et de ne rendre mutable qu'une section)

let mailPrompt = Browser.inputBox('Vérifier corps du mail et modifier si besoin :', 'Corp mail inital : '+body, Browser.Buttons.OK_CANCEL);
  if (mailPrompt !== ""){body = mailPrompt}

5 : convertir la liste d'adresse mail pour envoyer le mail à tous en même temps (comme dis précédemment il est possible de faire 1 mail / adresse, ou même un seul mail en les mettant en Cci, tout dépend des besoins)

  let recipients = emails.flat().filter(Boolean).join(', ');

6 : on envoie le mail

         MailApp.sendEmail({
      to: recipients,
      subject: objectTitle+' '+objectDate,
      htmlBody: body
    });

Voici le script au global :

function sendMail() {
  let ss = SpreadsheetApp.getActiveSpreadsheet();
  let sheet = ss.getActiveSheet();
  let emails = sheet.getRange('D4:D20').getValues();
  let objectDate = sheet.getRange('B2').getDisplayValue();
  let objectTitle = sheet.getRange('B3').getValue();
  let body = "Bonjour, voici le document,...";
  let mailPrompt = Browser.inputBox('Vérifier corps du mail et modifier si besoin :', 'Corp mail inital : '+body, Browser.Buttons.OK_CANCEL);
  if (mailPrompt !== ""){body = mailPrompt}
  let recipients = emails.flat().filter(Boolean).join(', ');
  MailApp.sendEmail({
      to: recipients,
      subject: objectTitle+' '+objectDate,
      htmlBody: body
    });
}

Bonjour Pierre,

désolé pour le delay de réponse. les fêtes ont été longues 😂.

Bonne année au passage :)

Merci beaucoup pour ton aide précieuse qui me permet d'y voir plus clair. malheureusement je n'ai pas encore réussi.

j'ai bien compris les étapes et en effet il s'agit bien d'un envoi commun à tous, avec le même message etc...

on va garder garder le corps de texte en dur pour l'instant mais je pense avoir compris la manière de stocker le message dans une cellule.

peux on aussi rappeler des cellules dans le corps du mail ?

par exemple : Bonjour à tous, ci joint le document pour "sheet.getRange('B3').getDisplayValue()" qui aura lieu le "sheet.getRange('B3').getDisplayValue()"

et quelle différence entre .getvalues() et .getDisplayValue () ?

Ensuite, est-il possible que le message pré rempli s'ouvre dans mon éditeur de mail ? (mail pour Mac en l'occurrence) ?

afin de pouvoir faire des modifications, ou ajouter des adresses mail, etc... ?

ça remplacerait le point n°4 dans ton explication.

Pour finir, je reçois bien le texte avec le corps de texte, mais dans l'objet je n'ai rien or il me semble qu'il devrait y avoir quelque chose :

subject: objectTitle+' '+objectDate,

autre question, il y a des cellules fusionnées dans le doc. par exemple A3 et B3. si je veux appeler ce qui est dedans je dois écrire A3 uniquement ou A3:A4 ?

un grand merci pour ton retour. ça m'aide beauocup.

bonne journée et d'ores et déjà un grand merci pour le temps passé

Bonjour,

Voici des réponses :

peux on aussi rappeler des cellules dans le corps du mail ?

Oui, dans ce cas le plus simple est de mettre les données dans des variables et ensuite les ajouter au mail, pour prendre en exemple la donnée située en B3, on la stocke dans la variable objectTitle, donc voici comment l'incorporer dans le corps du mail :

  let body = "Bonjour, voici le document,... ayant pour titre "+objectTitle+" bonne récéption ";

Concernant la manière dont on stocke les données sheet > script :

.getValue() = stocke une valeur.

.getDisplayValue() = stocke la valeur affichée, par exemple une date, avec getValue() donne : 44462 avec getDisplayValue() donne : 23/09/2021.

Lorsque c'est au pluriel, .getValues() par exemple, on stocke plusieurs valeurs en même temps.

Donc, si on veut une seule donnée, qui est un nombre, du texte, on va utiliser .getValue(), si c'est une date .getDisplayValue(), si on veut stocker plusieurs données d'un coup, on utilise ces mêmes fonctions, mais au pluriel.

Pour ce qui est de la vérification des mails et du corps du mail avant envoi, il n'est pas possible (simplement) d'afficher une fenêtre Gmail en brouillon (c'est possible mais on passe une marche niveau complexité), vois déjà si ça fonctionne ainsi.

Merci,

j'ai bien avancé...

reste encore quelques modifications :

comment aller à la ligne dans le corps du mail ?

 let body = "Bonjour, voici la feuille de route pour " +objectTitle+ "le " +objectDate+ " à " +objectLieu+ ". Merci d'arriver en avance afin de signer vos contrats autour d'un café. N'oubliez pas vos EPI obligatoires : gants, casque, chaussures de sécurité. A bientôt";

j'ai essayé <br> comme j'ai pu le lire sur le net mais je dois mal me dérouiller.

voici le résultat attendu :

let body = "Bonjour, voici la feuille de route pour " +objectTitle+ "le " +objectDate+ " à " +objectLieu+ ".
Merci d'arriver en avance afin de signer vos contrats autour d'un café.
N'oubliez pas vos EPI obligatoires : gants, casque, chaussures de sécurité.

A bientôt";

Autre chose plus important, je m rend compte que j'ai oublié le principal... la pièce jointe du mail... qui est généré par un autre code dont je dispose (la bas ayant été créé par une autre personne)

voici le code :

function onOpen() {
  const ui = SpreadsheetApp.getUi(); 
   ui.createMenu("GED").addItem("Enregistrer le PDF ↓ ","savePDF").addToUi();
}

function savePDF()
{
 // SELECTIONNER LA FEUILLE A SAUVEGARDER
  const ss = SpreadsheetApp.getActiveSpreadsheet(); 
  const sheet = ss.getActiveSheet();

//URL de SS ?
    const ssUrl = ss.getUrl();
    const sheetId= sheet.getSheetId();

    const url = ssUrl.replace(/\/edit.*$/,'')
      + '/export?exportformat=pdf&format=pdf'
      + '&size=LETTER'
      + '&portrait=true'
      + '&fitw=true'
      + '&top_margin=0.50'              
      + '&bottom_margin=0.50'          
      + '&left_margin=0.50'             
      + '&right_margin=0.50'           
      + '&sheetnames=false'
      + '&printtitle=false'
      + '&pagenum=false'
      + '&gridlines=false'
      + '&fzr=FALSE'
      + '&gid='+sheetId;

// CREER LE PDF A PARTIR DE L'URL
 // var token = ScriptApp.getOAuthToken();
  const docurl = UrlFetchApp.fetch(url);
  const pdf = docurl.getAs('application/pdf');

  const file = DriveApp.createFile(pdf);

// RÉCOLTER LES INFORMATIONS DANS LE SHEET POUR COMPOSER LE NOM DU DOCUMENT
  const docId = sheet.getRange('F5').getValue();
  const clientName =  sheet.getRange('C3').getValue();

  const docDate = sheet.getRange('F5').getValue();

  // Concaténons le tout 
  const docName = docId+"_CODIFS_" ;

// RENOMMER ET COPIER LE PDF DANS LE BON DOSSIER  
 /*
   ATTENTION IL FAUT ADAPTER LE CODE AVEC L'ID DU FOLDER DE DESTINATION
   https://drive.google.com/open?id=1r4rc-qwMvWhg0yFeiOG05VcUq_91KcwQ
  */

  const folder = DriveApp.getFolderById("1rlLM5EdOrSGm_d_nsWpRPr1KKj9bDG7n"); 
  const finalFile = file.makeCopy(docName,folder);

  //SUPPRIMER LE PDF ORIGINAL
  file.setTrashed(true);  

  //RÉCUPÉRER LE LIEN
     const docUrl = finalFile.getUrl();

//ajouter l'urL dans la GED.
    const sheetGed = ss.getSheetByName('GED');
    sheetGed.appendRow([new Date(),docId,docUrl,docName]);

// envoyer le document au client 
const clientEmail =  sheet.getRange('C7').getValue();
const message = "Bonjour"+"<p>Veuillez trouver ci-joint le devis "+docName+"</p>"+"<a href='"+docUrl+"'>Cliquez ici pour ouvrir le devis.</a>"; 
MailApp.sendEmail({to:clientEmail , subject: "Votre devis "+docName, htmlBody:message}) ; 

// ANNONCER LA RÉUSSITE DE CRÉATION DU DOCUMENT
 const ui = SpreadsheetApp.getUi(); 
ui.alert('Well done\n\nLe devis '+ docId +' a bien été créé\nIl porte le nom : '+docName+'\n\nLe lien a été ajouté dans la GED.');

     openWindow(docUrl);
}

// Ouvrir le document dans une nouvelle fenêtre : 
function openWindow(url)
{
 let htmlContent = 'Le document a été créé.  <a href="'+url+'" target="_blank">Cliquez ici pour l\'ouvrir</a>'+
 '<script>const thisWindowOpen = window.open("'+url+'" , "_blank", "resizable,scrollbars,status");  </script>';

  const html = HtmlService.createHtmlOutput(htmlContent)
    .setHeight(100)
    .setWidth(500);

const ui = SpreadsheetApp.getUi();
   ui.showModalDialog(html, "Ouverture en cours.");
}

comment faire pour que ce pdf soit en pièce jointe du mail ?

actuellement le script créé le pdf puis une popup s'ouvre m'invitant à le télécharger.

Dernière chose, le mail est envoyé via l'adresse gmail lié au au drive dans lequel j'ouvre le google sheet si je comprend bien. Or mon drive est personnel et mon ficher est professionnel. C'est donc pour ça que j'aurais aimé que le mail se prépare dans mon logiciel de messagerie afin afin que je puisse choisir mon adresse mail d'envoi et ma signature.

est-ce faisable ?

sachant que le document est collaboratif et qu'on est 5 ou 6 à y avoir accès, avec autant d'adresse mail et de signature différentes...

merci beaucoup pour ton aide.

Bonjour Pierre,

pardon je me suis perdu dans mes idées et j'ai mélangé plusieurs fichiers dans ma tête.

je n'ai pas besoin d'envoyer un fichier pdf généré par ce google sheet, mais un autre fichier stocké dans mon ordinateur.

c'est donc pour cela que je souhaitais que le script ouvre mon logiciel de messagerie, afin de pouvoir rajouter une pièce jointe issue de mon ordinateur.

merci par avance

Bonjour Pierre,

je me permets un petit up du sujet... je n'arrive pas à avancer...

merci beaucoup

Bonjour,

De ce que je sais, pas possible d'ouvrir en popup un email "pré-fait" dans votre messagerie.

Par contre si dans votre tableau vous avez les liens vers les fichiers à envoyer, il y a sans doute moyen de les joindre aux mails

bonjour et merci pour votre réponse.

ça me parait compliqué d'avoir le lien dans le tableau.

autre idée, il n'est pas possible dans le popup que vous avez créé, d'avoir un bouton : "ajouter une pièce jointe" qui irait chercher le fichier en question ?

sans passer par ma messagerie ?

Donc, dans la popup, on ajoute un bouton "ajouter une pièce jointe", comment ensuite le script sait quelle fichier joindre au mail ?

Donc, dans la popup, on ajoute un bouton "ajouter une pièce jointe", comment ensuite le script sait quelle fichier joindre au mail ?

je ne comprends pas. si on insère la pièce jointe, le script ne reconnais pas la pièce jointe qu'on vient d'insérer?

si "ajouter une pièce jointe" permet de choisir un fichier sur l'ordinateur par glisser déposer c'est bon non ?

Rien n'est automatique

Je pense comprendre, quand on clique sur le bouton "ajouter une pièce jointe" vous voulez qu'un explorateur fichier s'ouvre, puis que vous sélectionnez le fichier à mettre en PJ ? si c'est bien cela qu'il vous faut, c'est faisable, mais en passant par du script bien plus complexe (combinaisons de GAS + HTML).

Voici comment ouvrir une popup HTML : (en GAS)

function openPopup() {
  var html = HtmlService.createHtmlOutputFromFile('popup')
    .setWidth(300)
    .setHeight(200);
  SpreadsheetApp.getUi().showModalDialog(html, 'Sélectionnez un fichier');
}

La popup HTML (sans CSS)

<!DOCTYPE html>
<html>
<head>
  <base target="_top">
</head>
<body>
  <input type="file" id="fileInput" />
  <button onclick="uploadFile()">Uploader le fichier</button>

  <script>
    function uploadFile() {
      var fileInput = document.getElementById('fileInput');
      var file = fileInput.files[0];

      google.script.run.withSuccessHandler(onFileUploaded).uploadFile(file);
    }

    function onFileUploaded(response) {
      alert(response);
    }
  </script>
</body>
</html>

Le traitement du fichier uploadé : (de retour en GAS)

function uploadFile(file) {
  var destinataire = 'xxx@gmail.com';
  var subject = 'coucou';
  var body = 'votre texte';
  var message = {
    to: destinataire,
    subject: subject,
    body: body,
    attachments: [file]
  };
  GmailApp.sendEmail(message);
}

ho bah zut j'y comprend rien 😂

Je pense comprendre, quand on clique sur le bouton "ajouter une pièce jointe" vous voulez qu'un explorateur fichier s'ouvre, puis que vous sélectionnez le fichier à mettre en PJ ?

oui c'est exactement ça.

par contre je dois remplacer tout ça par ce que j'avais avant ?

Rechercher des sujets similaires à "script envoi mail"