Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 61

Final Project - Part 3: Database Storage, Email Reporting, and Error Handling

Recommended resources

Bonjour !

Dans la leçon précédente, vous avez construit la partie centrale de notre projet final : un workflow qui collecte, transforme et enrichit des données produit. Nous disposons maintenant d'une liste d'objets JSON propres, contenant des prix convertis et des descriptions générées par IA, prête à être exploitée.

Nous voici à la dernière étape de notre projet et de ce cours. L'objectif d'aujourd'hui est de finaliser notre système de bout en bout en implémentant le stockage en base de données, le reporting par email, et la gestion des erreurs. Nous allons transformer notre workflow de traitement en une solution d'automatisation complète, robuste et prête pour la production.

1. Stockage des Données en Base de Données

Pour que notre veille soit utile sur le long terme, nous devons stocker les données collectées. Cela nous permettra d'analyser les tendances, de comparer les produits dans le temps et de ne pas perdre le fruit de notre scraping quotidien.

Comme vous êtes un consultant IT, la mise en place d'une base de données locale ne devrait pas vous poser de problème. Pour cet exercice, je vous suggère d'utiliser PostgreSQL via Docker, ce qui est une solution standard et robuste.

A. Préparation de la base de données

  1. Lancez une instance PostgreSQL (par exemple, avec Docker).

  2. Connectez-vous à cette base et créez une table pour stocker nos produits. Voici un script SQL que vous pouvez utiliser :

    CREATE TABLE products (
        id SERIAL PRIMARY KEY,
        name VARCHAR(255) NOT NULL,
        price_usd NUMERIC(10, 2),
        price_eur NUMERIC(10, 2),
        product_url VARCHAR(255) UNIQUE NOT NULL,
        image_url VARCHAR(255),
        description TEXT,
        created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
    );
    

    L'instruction UNIQUE sur product_url est cruciale : elle nous empêchera d'insérer des doublons et nous servira à identifier les produits existants.

B. Implémentation de la logique "Upsert" dans n8n

Reprenez votre workflow de la leçon précédente. Nous allons y ajouter la logique de stockage. L'objectif est d'insérer les nouveaux produits et de mettre à jour ceux qui existent déjà (une opération "UPSERT").

L'article suivant, bien que centré sur HubSpot, montre une logique de synchronisation avec une base de données Postgres qui est très pertinente ici.

10 exemples de workflows n8n pour l'automatisation d'entreprise

Lisez cette section de l'article de Hostinger pour voir un exemple concret de synchronisation de données avec une base Postgres. Portez une attention particulière à l'utilisation des nœuds Postgres, IF et à la gestion des branches pour l'insertion ou la mise à jour.

Concentrez-vous sur la partie "Synchronisation des données clients". Observez comment le workflow utilise un premier nœud pour vérifier l'existence d'un enregistrement, un nœud IF pour diviser le flux, puis des nœuds distincts pour insérer (insert) ou mettre à jour (update). C'est exactement le modèle que nous allons suivre.

Voici comment l'appliquer à notre workflow, après le dernier nœud SET: Add AI Description :

  1. Ajoutez un nœud Postgres (ou MySQL si vous préférez) :

    • Renommez-le DB: Check if Exists.
    • Credentials : Configurez vos identifiants de connexion à la base de données.
    • Operation : Execute Query.
    • Query : SELECT id FROM products WHERE product_url = '{{ $json.productURL }}';
    • Cette requête retournera un item si le produit existe, et rien dans le cas contraire.
  2. Ajoutez un nœud IF :

    • Condition : Configurez-le pour vérifier si le nœud précédent a retourné des données. Choisissez Number et entrez l'expression {{ $items('DB: Check if Exists').length }}.
    • Laissez l'opération sur Is Greater et la valeur sur 0.
    • La sortie true correspondra aux produits existants, la sortie false aux nouveaux produits.
  3. Branche true (Mise à jour) :

    • Connectez un autre nœud Postgres à la sortie true du nœud IF.
    • Renommez-le DB: Update Product.
    • Operation : Update.
    • Table : products.
    • Update Key : product_url. C'est la colonne à utiliser pour trouver la bonne ligne à mettre à jour.
    • Columns : Mappez les champs de votre item n8n aux colonnes de la table à mettre à jour (ex: price_eur, description, updated_at). Pour updated_at, vous pouvez utiliser l'expression {{ new Date().toISOString() }}.
  4. Branche false (Insertion) :

    • Connectez un troisième nœud Postgres à la sortie false du nœud IF.
    • Renommez-le DB: Insert Product.
    • Operation : Insert.
    • Table : products.
    • Columns : Mappez les champs de votre item (name, price_usd, price_eur, productURL, etc.) aux colonnes de votre table.

À ce stade, votre workflow peut sauvegarder de manière fiable les données enrichies.


2. Reporting Synthétique par Email

Une fois les données stockées, il est utile d'envoyer un rapport pour confirmer que le travail a été fait et pour donner un aperçu des nouveautés.

La vidéo ci-dessous présente un workflow complexe de reporting. Bien qu'il utilise l'IA pour l'analyse, il illustre parfaitement comment agréger des données et générer un rapport HTML professionnel par email, ce qui est notre objectif.

AI-Powered Business Performance Reporting Automation with n8n & Gemini 2.5 | Full Workflow Tutorial

Regardez cette vidéo de syncbricks pour vous inspirer sur la création d'un rapport de performance complet. Nous n'allons pas recréer l'analyse par IA, mais concentrez-vous sur la manière dont les données sont formatées en HTML et envoyées par email.

Portez votre attention sur deux aspects : Transformation en HTML (02:30 - 04:16) : Observez comment des données issues de plusieurs sources sont transformées en tables HTML. Envoi de l'email (06:29 - 08:06) : Notez la configuration du nœud d'envoi d'email (ici Outlook, mais le principe est identique pour SMTP/Gmail) et l'utilisation du contenu HTML généré dans le corps du message.

Implémentons cela :

  1. Agréger les résultats : Après vos nœuds de base de données, vous avez potentiellement plusieurs items qui ont été traités. Pour envoyer un seul email de résumé, il faut d'abord les regrouper.

    • Ajoutez un nœud NoOp (No Operation) après les nœuds DB: Update Product et DB: Insert Product. C'est une bonne pratique pour avoir un point de jonction clair. Connectez les deux sorties des nœuds DB à ce nœud NoOp.
    • Après le NoOp, ajoutez un nœud Item Lists.
    • Operation : Summarize. Cela va agréger tous les items en un seul. Laissez les options par défaut pour l'instant. Le but est de s'assurer que le nœud suivant ne s'exécute qu'une seule fois.
  2. Ajoutez un nœud Send Email :

    • Credentials : Configurez vos identifiants SMTP.
    • To : Votre adresse email.
    • Subject : Rapport de veille concurrentielle du {{ $now.toFormat('dd/MM/yyyy') }}.
    • HTML : Activez cette option pour envoyer un email formaté.
    • Body : C'est ici que la magie opère. Nous allons construire une table HTML dynamiquement avec les données de tous les produits traités. Notez que $items() fait référence à tous les items entrant dans ce nœud.
    <h1>Rapport de Veille Concurrentielle</h1>
    <p>Le workflow a traité avec succès {{ $items().length }} produits.</p>
    
    <h2>Nouveaux Produits Détectés :</h2>
    <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse; width: 100%;">
        <thead>
            <tr style="background-color: #f2f2f2;">
                <th>Produit</th>
                <th>Prix (EUR)</th>
                <th>URL</th>
            </tr>
        </thead>
        <tbody>
            {{
                $items('NoOp').map(item => `
                    <tr>
                        <td>${item.json.name}</td>
                        <td>${item.json.priceEUR.toFixed(2)} €</td>
                        <td><a href="${item.json.productURL}">Voir le produit</a></td>
                    </tr>
                `).join('')
            }}
        </tbody>
    </table>
    <p>Fin du rapport.</p>
    

    Note : Nous utilisons $items('NoOp') pour être sûrs de récupérer la liste complète des produits traités avant l'agrégation.

Exécutez cette partie : vous devriez recevoir un email de synthèse bien formaté !


3. Gestion Robuste des Erreurs

Un workflow de production doit être résilient. Que se passe-t-il si l'API de devise est en panne ? Si le site à scraper est inaccessible ? Sans gestion d'erreurs, le workflow échouera silencieusement.

La meilleure pratique dans n8n est de créer un workflow d'erreur dédié.

La vidéo officielle de n8n ci-dessous est le guide de référence pour construire un tel workflow.

n8n Advanced Course (5/8) - Error workflows

Cette vidéo du cours avancé de n8n est essentielle. Elle explique le concept du workflow d'erreur et vous guide pas à pas dans sa construction. Regardez-la attentivement.

Suivez la construction du workflow d'erreur de bout en bout (00:00 - 07:00). Concentrez-vous sur : Le rôle du nœud Error Trigger et les informations qu'il fournit. Comment enrichir les données de l'erreur (par exemple, avec le nom du workflow). Comment formater un message d'alerte clair et l'envoyer au bon destinataire (par email dans notre cas).

Maintenant, créons notre propre gestionnaire d'erreurs.

  1. Créez un NOUVEAU workflow : Nommez-le [Projet Final] - Gestionnaire d'Erreurs.

  2. Ajoutez un nœud Error Trigger : C'est le point d'entrée. Il se déclenchera automatiquement quand un autre workflow (configuré pour l'utiliser) échouera.

  3. Ajoutez un nœud Set : Pour formater un message clair.

    • Renommez-le Format Error Message.

    • Créez une nouvelle valeur de type String nommée errorMessage.

    • Utilisez une expression pour construire le message :

      🚨 Erreur critique dans le workflow ! 🚨
      
      Workflow: {{ $json.execution.workflowName }}
      Erreur: {{ $json.error.message }}
      Nœud en échec: {{ $json.error.node.name }} (type: {{ $json.error.node.type }})
      
      Veuillez vérifier l'exécution ici :
      {{ $json.execution.url }}
      
  4. Ajoutez un nœud de notification : Send Email ou Slack selon votre préférence, et envoyez le contenu de errorMessage.

n8n Error Tracking Workflow with Reporting
Votre workflow d'erreur devrait ressembler à ce schéma : un déclencheur, des étapes de formatage/log, et une étape de notification.

Dernière étape, et la plus importante :

  1. Revenez à votre workflow principal ([Projet Final] - Collecte et Transformation...).
  2. Allez dans les Settings (icône d'engrenage en haut à gauche).
  3. Dans la section Error Workflow, sélectionnez votre nouveau workflow [Projet Final] - Gestionnaire d'Erreurs.
  4. Sauvegardez.

Votre système est maintenant équipé d'un filet de sécurité professionnel.


4. Finalisation et Activation

Nous avons assemblé toutes les briques. Il ne reste plus qu'à finaliser le workflow principal.

  1. Remplacez le déclencheur : Dans le workflow principal, supprimez le nœud Start et remplacez-le par un nœud Cron.
  2. Configurez le Cron : Réglez-le pour s'exécuter à la fréquence désirée, par exemple, tous les jours à 2h du matin (0 2 * * *).
  3. Activez les workflows :
    • Activez le workflow principal en basculant l'interrupteur Active en haut à droite.
    • Faites de même pour le workflow d'erreur. Un workflow d'erreur doit être actif pour pouvoir être déclenché.

Conclusion

Félicitations ! Vous êtes allé au bout de ce projet et de ce cours. Vous avez conçu et implémenté un système d'automatisation complet, robuste et intelligent.

Ce que vous avez accompli dans cette leçon :

  • Intégration de base de données : Vous avez mis en place une logique "upsert" pour stocker les données de manière persistante et fiable.
  • Reporting dynamique : Vous avez créé un rapport de synthèse HTML envoyé par email, démontrant votre maîtrise des expressions pour formater des données complexes.
  • Gestion d'erreurs de production : Vous avez implémenté la meilleure pratique en matière de résilience avec un workflow d'erreur dédié, préparant votre automatisation pour le monde réel.

Vous disposez maintenant de toutes les compétences fondamentales et avancées pour aborder sereinement n'importe quel projet d'automatisation avec n8n. Les prochaines étapes pour vous pourraient être d'explorer la création de nœuds personnalisés, l'utilisation de l'API de n8n pour piloter des workflows à distance, ou l'intégration de la gestion de version avec Git.

Le champ des possibles est vaste. Continuez à expérimenter et à automatiser