Aller au contenu
Docs

Tutoriel

Envoyer des e-mails avec Node.js

Envoyez des e-mails depuis Node.js avec le SDK @emailit/node ou Nodemailer via SMTP, et vérifiez les webhooks Emailit dans une route Express.

Mis à jour le 1 oct. 2026

Ce guide montre comment envoyer des e-mails depuis une application Node.js avec le SDK officiel @emailit/node, comment utiliser plutôt Nodemailer via SMTP, et comment recevoir des webhooks signés dans Express.

Prérequis

  • Node.js 18 ou version ultérieure.
  • Un domaine d’envoi vérifié, par exemple acme.com.
  • Une clé API. Une clé Sending Only suffit pour envoyer.
  • Tant que votre espace de travail n’a pas l’accès production, vous ne pouvez envoyer qu’aux adresses e-mail des comptes des membres de l’espace de travail. Utilisez votre propre adresse pendant vos tests.

Installer le SDK

Terminal
npm install @emailit/node

Le paquet est uniquement au format ESM. Utilisez la syntaxe import, ou await import('@emailit/node') depuis du code CommonJS.

Configurer votre clé API

Ne mettez pas la clé dans votre code. Placez-la dans une variable d’environnement :

.env
EMAILIT_API_KEY=secret_••••••••••••••••••••••••••••••••

Chargez le fichier avec node --env-file=.env (Node.js 20.6 et versions ultérieures), un paquet comme dotenv ou les paramètres de secrets de votre plateforme. Ajoutez .env à .gitignore.

Envoyer un e-mail

Créez un seul client et réutilisez-le d’une requête à l’autre :

send.mjs
import { Emailit } from '@emailit/node';

const emailit = new Emailit(process.env.EMAILIT_API_KEY);

const email = await emailit.emails.send({
  from: 'Acme <hello@acme.com>',
  to: 'ada@example.com',
  subject: 'Welcome to Acme',
  html: '<p>Thanks for signing up.</p>',
  text: 'Thanks for signing up.',
});

console.log(email.id); // em_…

Exécutez-le avec node --env-file=.env send.mjs. L’e-mail apparaît dans Email APIEmails en quelques secondes.

Dans une application Express, envoyez depuis la route qui déclenche l’e-mail :

server.mjs
import express from 'express';
import { Emailit } from '@emailit/node';

const app = express();
const emailit = new Emailit(process.env.EMAILIT_API_KEY);

app.post('/signup', express.json(), async (req, res) => {
  const { email } = req.body;
  // Create the user here, then send the welcome email.
  const sent = await emailit.emails.send({
    from: 'Acme <hello@acme.com>',
    to: email,
    template: 'welcome',
    variables: { email },
  });
  res.status(201).json({ emailId: sent.id });
});

app.listen(3000);

template accepte un alias de modèle ou un ID tem_, et variables le complète. Consultez Modèles et la liste complète des champs dans Envoyer un e-mail.

Gérer les erreurs

Le SDK lève des erreurs typées : vous pouvez donc réagir à chaque type d’échec :

JavaScript
import {
  AuthenticationException,
  RateLimitException,
  UnprocessableEntityException,
  ApiErrorException,
} from '@emailit/node';

try {
  await emailit.emails.send(message);
} catch (err) {
  if (err instanceof RateLimitException) {
    // 429: wait err.jsonBody.retry_after seconds, then retry
  } else if (err instanceof AuthenticationException) {
    // 401: the API key is missing or invalid
  } else if (err instanceof UnprocessableEntityException) {
    // 422: for example, the from domain isn't verified
  } else if (err instanceof ApiErrorException) {
    console.error(err.httpStatus, err.jsonBody);
  } else {
    throw err;
  }
}

Envoyer plutôt via SMTP

Si votre application utilise déjà Nodemailer, faites-le pointer vers le relais SMTP Emailit. Installez-le avec npm install nodemailer :

mailer.mjs
import nodemailer from 'nodemailer';

const transporter = nodemailer.createTransport({
  host: 'smtp.emailit.com',
  port: 587,
  secure: false, // upgraded with STARTTLS after connecting
  requireTLS: true,
  auth: {
    user: 'emailit',
    pass: process.env.EMAILIT_API_KEY,
  },
});

const info = await transporter.sendMail({
  from: 'Acme <hello@acme.com>',
  to: 'ada@example.com',
  subject: 'Welcome to Acme',
  text: 'Thanks for signing up.',
  html: '<p>Thanks for signing up.</p>',
});

console.log(info.response); // 250 2.0.0 OK: queued as em_…

Pour le port 465, définissez port: 465 et secure: true. Si votre réseau bloque le port 587, utilisez 2525 ou 2587 avec les mêmes paramètres. Consultez Paramètres SMTP.

Recevoir des webhooks

Créez un webhook qui pointe vers https://your-app.com/webhooks/emailit et copiez son secret de signature (whsec_…) dans EMAILIT_WEBHOOK_SECRET.

Emailit signe chaque requête avec un HMAC-SHA256 de timestamp.rawBody : la route doit donc lire le corps brut. Utilisez express.raw() sur cette route, pas express.json() :

webhooks.mjs
import express from 'express';
import { createHmac, timingSafeEqual } from 'node:crypto';

function verifyEmailitSignature(rawBody, signature, timestamp, secret) {
  if (!signature || !timestamp) return false;
  const age = Math.abs(Math.floor(Date.now() / 1000) - Number(timestamp));
  if (!Number.isFinite(age) || age > 300) return false; // reject replays older than 5 minutes
  const expected = createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest('hex');
  const a = Buffer.from(expected);
  const b = Buffer.from(signature);
  return a.length === b.length && timingSafeEqual(a, b);
}

export const webhooks = express.Router();

webhooks.post('/webhooks/emailit', express.raw({ type: 'application/json' }), (req, res) => {
  const rawBody = req.body.toString('utf8');
  const valid = verifyEmailitSignature(
    rawBody,
    req.get('x-emailit-signature'),
    req.get('x-emailit-timestamp'),
    process.env.EMAILIT_WEBHOOK_SECRET,
  );
  if (!valid) return res.status(401).send('Invalid signature');

  // The body is an array of up to 100 events.
  const events = JSON.parse(rawBody);
  for (const event of events) {
    switch (event.type) {
      case 'email.delivered':
        // event.data.object.id is the em_ ID
        break;
      case 'email.bounced':
      case 'email.complained':
        // stop emailing event.data.object.to
        break;
    }
  }

  res.sendStatus(200);
});

Montez le routeur avec app.use(webhooks) avant tout middleware global express.json(). Renvoyez un 2xx dans les 30 secondes ; pour toute autre réponse, Emailit réessaie. Pour plus de détails, consultez Signature des requêtes et Nouvelles tentatives et échecs.

Conseils pour la production

  • Limitez la portée de la clé. Utilisez sur le serveur d’application une clé Sending Only limitée à votre domaine d’envoi. Réservez les clés Full Access aux scripts d’administration.
  • Restez sous votre limite de débit. Par défaut, les nouveaux espaces de travail peuvent envoyer 2 e-mails par seconde et 5 000 par jour, partagés entre l’API et le SMTP. Envoyez les lots volumineux depuis une file d’attente. Avec Nodemailer, pool: true, rateLimit: 2 maintient un transport en pool à 2 messages par seconde. Consultez Limites.
  • Sécurisez les relances. Si vous relancez un envoi après un timeout, envoyez un en-tête Idempotency-Key pour qu’Emailit n’envoie pas deux fois. Le SDK ne définit pas d’en-têtes personnalisés : utilisez donc fetch pour ces appels ; consultez Idempotence.
  • Traitez les webhooks de façon idempotente. Enregistrez chaque event_id traité et ignorez les doublons, et effectuez les traitements lents dans une tâche en arrière-plan après avoir renvoyé 200.
  • Vous utilisez TypeScript ? Le SDK n’a pas encore de déclarations de types. Ajoutez declare module '@emailit/node'; à un fichier .d.ts de votre projet.

Étapes suivantes

Pièces jointes, programmation, suivi et métadonnées.
Tous les événements et leur payload.
Route handlers et server actions.
Toutes les bibliothèques officielles.

Cette page vous a-t-elle été utile ?

Merci pour votre retour.

Merci, nous lisons chaque message.