Générer et envoyer par mail un pdf récapitulatif pour l’usager suite à la saisie d’un formulaire

Ma solution très bricolo qui ne demande qu’à être améliorée et simplifiée :

1 et 2. Pour configurer le Webhook et le noeud Grist, je vous renvoie au post d’ @audezu : Workflows basiques avec n8n

3. Un premier nœud Code renvoie le dernier enregistrement dans la table Grist.
Deux remarques :

  • Normalement, un bon paramétrage du nœud Grist suffirait pour cette opération mais je n’y suis pas parvenu.
  • cette partie de code pourrait être intégrée au nœud suivant mais j’ai préféré les séparer pour la lisibilité (et parce que j’espère arriver à régler le point ci-dessus)
  • Une troisième par souci d’honnêteté : c’est DeepSeek qui a généré ce code comme celui du deuxième nœud code.
const allRecords = $input.all();
console.log(`📊 Reçu ${allRecords.length} enregistrements`);

if (allRecords.length === 0) return [];

// Affiche les timestamps pour vérifier
allRecords.forEach((record, index) => {
  console.log(`Record ${index}: ${record.json.rec_time}`);
});

const lastRecord = allRecords.reduce((newest, current) => {
  return new Date(current.json.rec_time) > new Date(newest.json.rec_time) 
    ? current 
    : newest;
});

console.log(`✅ Dernier enregistrement: ${lastRecord.json.rec_time}`);
return [lastRecord];

4. Le deuxième nœud code génère un fichier pdf :

  • récupère les valeurs utiles du noeud Grist
  • convertit les dates UNIX/Timestamp en dd/mm/yyyyy
  • génère un squelette html et le remplit avec les valeurs
  • génère un fichier html à partir du modèle rempli ci-avant.
//récupère les valeurs utiles du noeud Grist
const { 
    eleve_nom, 
    eleve_prenom,
    eleve_ddn,
    resp1_qualite,
    resp1_nom,
    resp1_prenom,
    resp1_adresse,
    resp1_cp,
    resp1_commune,
  
} = items[0].json;

// date UNIX/Timestamp => lisible par les humains

const date = new Date(eleve_ddn * 1000);
const jour = String(date.getDate()).padStart(2, '0');
const mois = String(date.getMonth() + 1).padStart(2, '0');
const annee = String(date.getFullYear());
const dateFormatee = `${jour}/${mois}/${annee}`;

// squelette html nourri aux valeurs de grist

const htmlContent = `
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>My HTML document</title>
  <style>
    </style>
</head>
<body>
 
${eleve_prenom} ${eleve_nom} est un sacr&eacute; zozo !

</body>
</html>
`;

//enregistre le contenu html dans un fichier
return [{
  json: {},
  binary: {
    data: {
      data: Buffer.from(htmlContent).toString('base64'),
      mimeType: 'text/html',
      fileName: 'index.html'
    }
  }
}];

5. le nœud HTTP Request / Gotenborg transforme le fichier html en pdf avec la configuration suivante (désolé pour les captures, je l’éditerai en texte dès que j’aurai plus de temps) :


6. le nœud Send mail.
Pas trop d’enjeu, si ce n’est de mettre le même nom pour la pièce-jointe (ici « example.pdf »).
A noter qu’on peut récupérer des valeurs du noeud Grist, par exemple le destinataire sou la forme :

{{ $('Grist').item.json.mail_du_destinataire }}

Merci pour vos éventuels retours pour alléger, améliorer…

2 « J'aime »