Comment faire Envoyer un e-mail via l'API en JavaScript (Tutoriel Node.js)
Ignorez le code standard SMTP. Ce guide vous montre comment envoyer des e-mails en Node.js en utilisant le API unifiée de messagerie Unipile - avec du code copié-collé pour Gmail, Outlook et SMTP en moins de 10 lignes de JavaScript.
import { UnipileClient } from 'unipile-node-sdk';
const client = nouveau UnipileClient(
process.env.UNIPILE_DSN,
process.env.UNIPILE_TOKEN
);
await client.email.envoyer({
account_id : 'VOTRE_IDENTIFIANT_DE_COMPTE',
à: [{ nom_afficher: 'Alice',
identifiant : 'alice@example.com' }],
sujet : 'Bonjour depuis Node.js',
body: 'Envoyé via Unipile !
'
});Exemple de nœud.js en 5 lignes
Si vous savez déjà ce qu'est un API d'envoi de courriels et je veux juste envoyer un code API JavaScript d'e-mail fonctionnel, le voici. Le tutoriel complet suit ci-dessous.
npm install unipile-node-sdkUNIPILE_DSN et UNIPILE_TOKEN à vous .env fichier.client.email.envoyer()account_id, à, sujet, ou encore corps. Fait.import { UnipileClient } from 'unipile-node-sdk';
const client = nouveau UnipileClient(
process.env.UNIPILE_DSN,
process.env.UNIPILE_TOKEN
);
const résultat = attente client.email.envoyer({
account_id : 'acc_xxxxxxxxxxxxxxxx',
à: [{
nom_affiché: 'Alice Martin',
identifier: 'alice@acme.com'
}],
sujet : 'Bonjour depuis Node.js',
body: 'Envoyé via l'API Unipile !
'
});
console.log(résultat); // { identifiant_suivi: 'msg_...' }Prérequis et installation
Avant de pouvoir utiliser le workflow JavaScript de l'API d'envoi d'e-mails en production, vous avez besoin de quatre éléments : une version prise en charge de Node.js, le SDK Unipile, une clé API et un point de terminaison DSN.
fetch et au plus haut niveau await. Node 20 LTS est recommandé pour la production. Vérifiez votre version avec node -v.api4.unipile.com:13444Les deux sont nécessaires pour initialiser le client..mjs fichiers ou régler "type":"module" en package.json. Pour CommonJS, dynamique importer() fonctionne aussi - exemples montrés ci-dessous.npm install unipile-node-sdkyarn add unipile-node-sdkpnpm ajouter unipile-node-sdk# Identifiants Unipile (ne jamais commiter ce fichier)
UNIPILE_DSN=https://api4.unipile.com:13444
UNIPILE_TOKEN=ton_jeton_d'accès_ici
# L'identifiant du compte de messagerie lié
EMAIL_ACCOUNT_ID=acc_xxxxxxxxxxxxxxxxAjouter .env à vous .gitignore. utiliser dotenv ou pour le Node 20.6+ natif --fichier-env drapeau pour le charger : node --env-file=.env send.mjs.
Connexion de votre premier compte de messagerie
Le API unifiée pour les e-mails utilise un seul account_id pour abstraire les différences entre les fournisseurs. Connectez un compte une fois, puis appelez client.email.envoyer() identiquement chez les trois fournisseurs.
Choisissez votre fournisseur ci-dessous pour voir l'extrait Node.js exact. L'account_id renvoyé est ce que vous stockez et réutilisez pour chaque envoi ultérieur.
import { UnipileClient } from 'unipile-node-sdk';
const client = nouveau UnipileClient(process.env.UNIPILE_DSN, process.env.UNIPILE_TOKEN);
// Étape 1 : générer un lien OAuth hébergé pour Gmail
const { url } = attente client.compte.créerLienAuthHébergé({
type: 'Google',
success_redirect_url: process.env.OAUTH_CALLBACK_URL,
failure_redirect_url: process.env.OAUTH_CALLBACK_URL + '?erreur=1',
});
// Étape 2 : redirigez votre utilisateur vers `url`
console.log('Rediriger l'utilisateur vers :', url) ;
// Étape 3 : Unipile POSTe le account_id à votre callback
// Stockez-le : process.env.EMAIL_ACCOUNT_ID = result.account_idimport { UnipileClient } from 'unipile-node-sdk';
const client = nouveau UnipileClient(process.env.UNIPILE_DSN, process.env.UNIPILE_TOKEN);
// Fonctionne pour Outlook personnel ET Microsoft 365 / Exchange Online
const { url } = attente client.compte.créerLienAuthHébergé({
type: 'MICROSOFT',
success_redirect_url: process.env.OAUTH_CALLBACK_URL,
failure_redirect_url: process.env.OAUTH_CALLBACK_URL + '?erreur=1',
});
// Rediriger l'utilisateur -> ils terminent le flux OAuth Microsoft
console.log('Rediriger l'utilisateur vers :', url) ;
// Voir : /syncing-emails-with-microsoft-graph-api-a-developers-guide/import { UnipileClient } from 'unipile-node-sdk';
const client = nouveau UnipileClient(process.env.UNIPILE_DSN, process.env.UNIPILE_TOKEN);
// SMTP/IMAP : passer les identifiants directement (pas de redirection OAuth)
const account = attente client.compte.create({
type: 'IMAP',
imap: {
username: process.env.IMAP_UTILISATEUR,
motDePasse: process.env.IMAP_MDP,
host: process.env.IMAP_HOTE,
port : 993,
},
smtp: {
username: process.env.IMAP_UTILISATEUR,
motDePasse: process.env.IMAP_MDP,
host: process.env.HÔTE_SMTP,
port : 587,
},
});
console.log(compte.compte_id); // enregistrer ceciEnvoyer votre premier e-mail depuis Node.js
Trois modèles prêts pour la production pour le workflow JavaScript de l'API d'envoi d'e-mails : texte brut, HTML avec CC/BCC et lecture de l'objet de réponse. Tous utilisent la même client.email.envoyer() appel.
import { UnipileClient } from 'unipile-node-sdk';
const client = nouveau UnipileClient(process.env.UNIPILE_DSN, process.env.UNIPILE_TOKEN);
const résultat = attente client.email.envoyer})
id_compte: process.env.EMAIL_ACCOUNT_ID,
à: [{ nom_afficher: 'Bob', identifier : 'bob@example.com' }],
sujet : 'Bienvenue sur la plateforme',
body: 'Salut Bob, ton compte est prêt.',
});
console.log(result.id_de_suivi); // msg_xxxxxxxxxxxxxxxxconst résultat = attente client.email.envoyer})
id_compte: process.env.EMAIL_ACCOUNT_ID,
à : [{ display_name: 'Alice', identifier : 'alice@acme.com' }],
cc: [{ display_name: 'Directeur', identifier : 'boss@acme.com' }],
bcc: [{ display_name: 'Audit', identifier : 'audit@internal.io' }],
sujet : 'Votre facture #1042',
// corps HTML - le fournisseur le rend nativement
body: `
Facture #1042
Montant dû : $299
Payer maintenant
`,
});
console.log('Envoyé :', result.tracking_id);| Champ | Type | Requis | Description |
|---|---|---|---|
account_id | chaîne | Requis | ID du compte de messagerie lié à partir duquel envoyer |
à | Destinataire[] | Requis | Tableau de {nom_affichage, identifiant} objets |
sujet | chaîne | Requis | Objet de l'e-mail |
corps | chaîne | Requis | Texte brut ou chaîne HTML |
cc | Destinataire[] | Facultatif | Destinataires en copie carbone |
CCI | Destinataire[] | Facultatif | Destinataires en copie carbone invisible |
from | Destinataire | Facultatif | Remplacer le nom d'affichage de l'expéditeur |
reply_to | chaîne | Facultatif | ID du message du fournisseur auquel répondre (fils) |
pièces jointes | Tableau | Facultatif | Tableau de [nom de fichier, Tampon] tuples |
en-têtes personnalisés | objet[] | Facultatif | Tableau personnalisé des en-têtes X |
options de suivi | objet | Facultatif | {ouvre, liens, étiquette} - activer le suivi d'ouverture/clic |
Obtenez votre clé API, liez un compte Gmail ou Outlook en quelques minutes, et exécutez les exemples Node.js de ce guide sur de vraies boîtes aux lettres.
Envoyer des pièces jointes dans Node.js
Le pièces jointes champ accepte un tableau de [nom de fichier, Tampon] tuples. Lire le fichier avec Node's fs.readFileSync ou en streaming avec fs.promises.readFile.
fs.promises.readFile(chemin) pour obtenir un tampon, puis passer ['nom_de_fichier.pdf', tampon]. Fonctionne avec PDF, DOCX, images, tout fichier binaire.cid: schéma. Référencez le même nom de fichier utilisé dans le tuple des pièces jointes : <img src="cid:logo.png">.pdfkit), collectez-le dans un Buffer et attachez-le sans écrire sur le disque. Sécurisé en production pour le serverless.import { UnipileClient } from 'unipile-node-sdk';
import promesses En tant que fs from 'noeud:fs';
const client = nouveau UnipileClient(process.env.UNIPILE_DSN, process.env.UNIPILE_TOKEN);
// Lire le fichier dans un tampon
const Tampon pdf = attente fs.lireFichier('./facture.pdf');
await client.email.envoyer({
account_id: process.env.EMAIL_ACCOUNT_ID,
à : [{ nom_affichage: 'Client', identifier : 'client@example.com' }],
sujet : 'Votre facture est jointe',
body: 'Veuillez trouver votre facture ci-jointe.
',
pièces jointes : [
['facture.pdf', pdfTampon], // [nom de fichier, Tampon]
],
});const [logo, rapport] = attente Promise.all([
fs.lireFichier('./logo.png'),
fs.lireFichier('./report.xlsx'),
]);
await client.email.envoyer})
id_compte: process.env.EMAIL_ACCOUNT_ID,
à : [ { display_name : 'Équipe', identifier : 'team@acme.com' }],
sujet : 'Rapport T1',
body:
Q1 Rapport
Voir la feuille de calcul ci-jointe pour plus de détails.
`,
pièces jointes : [
['logo.png', logo], /* en ligne via cid:logo.png dans le corps */
['rapport.xlsx', rapport], // pièce jointe régulière
],
});Réponses, Fils & Suivi
Allez au-delà des envois basiques : réponses de fils, en-têtes personnalisés pour l'idempotence, suivi d'ouverture/clics via webhooks, et envoyer un e-mail au nom d'un utilisateur.
1
Répondre à un fil de discussion
Transmettez l'ID du message du fournisseur (renvoyé dans la réponse d'envoi d'origine ou dans la liste des e-mails) comme reply_to. Unipile injecte le correct En réponse à et Références en-têtes afin que les fils de discussion soient correctement répertoriés dans Gmail, Outlook et les clients IMAP.
await client.email.envoyer})
id_compte: process.env.EMAIL_ACCOUNT_ID,
à : [ { display_name : 'Alice', identifier : 'alice@acme.com' }],
sujet : 'Re: Votre question',
body: 'Merci de votre intérêt ! Voici la réponse...
',
// ID du message du fournisseur de l'e-mail d'origine
répondre_à : 'msg_xxxxxxxxxxxxxxxx',
});
2
En-têtes personnalisés et idempotence
Utilisez en-têtes personnalisés pour ajouter n'importe quoi X- en-tête. Un schéma courant est X-Idempotency-Key pour éviter les envois dupliqués lors de la nouvelle tentative après un délai d'attente réseau.
import { uuid aléatoire } from 'nœud:crypto';
await client.email.envoyer})
id_compte: process.env.EMAIL_ACCOUNT_ID,
à : [ { display_name : 'Bob', identifier : 'bob@example.com' }],
sujet : 'Confirmation de commande #9981',
body: 'Votre commande est confirmée.
',
custom_headers: [
{ name: 'X-Clé-Idempotence', valeur : randomUUID) },
{ nom : 'X-Order-ID', valeur: '9981' },
],
});
3
Suivi des ouvertures et des clics via les webhooks
Activer le suivi dans options de suivi. Unipile déclenche un événement webhook (email.ouvert / email.lien_cliqué) à votre URL de webhook enregistrée avec le étiquette vous vous placez ici afin de pouvoir corréler les événements avec vos identifiants internes.
await client.email.envoyer})
id_compte: process.env.EMAIL_ACCOUNT_ID,
à : [ { display_name : 'Plomb', identifier : 'lead@prospect.com' }],
sujet : 'Suite à votre essai',
body: 'Bonjour, je voulais prendre des nouvelles...
',
tracking_options: {
ouvertures : true, // déclenche le webhook fire.opened
liens : true, // déclenche le webhook email.link_clicked
étiquette : 'crm_lead_12345', // votre ID de corrélation interne
},
});
4
Envoi au nom d'un autre utilisateur
Lors de la construction d'applications SaaS multi-locataires, chaque utilisateur final associe son propre compte de messagerie. Stocker le account_id par utilisateur dans votre base de données et le transmettre au moment de l'envoi. Voir le guide complet sur Comment envoyer un e-mail au nom d'un utilisateur.
// Chaque utilisateur a son propre account_id lié stocké dans votre base de données
async function envoyerEnTantQuUtilisateur(userId, à, sujet, corps) {
const utilisateur = attente base de données.getUser(userId);
return client.email.envoyerid_compte: user.unipile_account_id, // par utilisateur
à, objet, corps,
});
}
// L'e-mail est envoyé depuis Gmail d'Alice, pas de notre adresse serveur
await envoyerEnTantQuUtilisateur('utilisatrice_alice', destinataires, sujet, corps);Travailler en Python ? Voir notre Implémentation Python guide.
Gestion des erreurs et nouvelles tentatives
Les pannes réseau et les limitations de débit sont inévitables à grande échelle. Voici un modèle async/await de qualité professionnelle pour votre API d'envoi d'e-mails implémentée en JavaScript, avec une stratégie de rétrogradation exponentielle et une journalisation structurée à l'aide de Winston ou Pino.
identifiant de suivi est rempli. Aucune nouvelle tentative nécessaire.Réessayer après en-tête. Utiliser un recul exponentiel.UNIPILE_TOKEN variable d'environnement. Ne pas réessayer - corriger les identifiants.account_id n'existe pas ou a été révoqué. Reliez le compte.import { UnipileClient } from 'unipile-node-sdk';
import logger from './logger.mjs'; // Winston or Pino instance
const client = new UnipileClient(process.env.UNIPILE_DSN, process.env.UNIPILE_TOKEN);
async function sendWithRetry(payload, maxAttempts = 4) {
let attempt = 0;
while (attempt < maxAttempts) {
try {
const result = await client.email.send(payload);
logger.info({ tracking_id: result.tracking_id }, 'Email sent');
return result;
} catch (err) {
const status = err?.status ?? err?.statusCode;
// Do not retry on client errors (4xx except 429)
if (status >= 400 && status !== 429 && status < 500) {
logger.error({ status, err }, 'Non-retryable error');
throw err;
}
attempt++;
if (attempt >= maxAttempts) throw err;
// Exponential backoff: 1s, 2s, 4s, 8s...
const delay = 1000 * 2 ** (attempt - 1);
logger.warn({ attempt, delay, status }, 'Retrying...');
await new Promise(r => setTimeout(r, delay));
}
}
}
// Usage
await sendWithRetry({
account_id: process.env.EMAIL_ACCOUNT_ID,
to: [{ display_name: 'User', identifier: 'user@example.com' }],
subject: 'Your report is ready',
body: 'Click to download.
',
});Bonnes pratiques de sécurité dans Node.js
Votre UNIPILE_TOKEN accorde un accès API complet. Ne l'exposez jamais côté client. Voir le complet Guide de sécurité des API d'e-mail pour des sujets avancés incluant DKIM, SPF et la rotation des jetons OAuth.
UNIPILE_TOKEN doit rester sur le serveur. Tout JavaScript côté navigateur – y compris les composants clients Next.js, le frontend React ou Vite – NE doit PAS importer directement le jeton./api/envoyer-email. Dans Express, un point de terminaison POST. Authentifiez d'abord vos propres utilisateurs, puis appelez le serveur Unipile côté serveur avec le jeton de l'environnement.account_id reste valide. Vous n'avez pas besoin de gérer vous-même l'expiration du jeton d'accès.// client.js - NE JAMAIS faire ça
const client = new UnipileClient(
'https://api4.unipile.com:13444',
'sk_live_xxxxxxxxxx' Démasqué !
);
// app/api/envoyer-email/route.js
exporter de manière asynchrone la fonction POST(req) {
// vérifier l'authentification d'abord
const session = await getServerSession();
if (!session) return new Response(null,{status:401});
const client = new UnipileClient(
process.env.UNIPILE_DSN, // réservé au serveur
process.env.UNIPILE_TOKEN // réservé au serveur
);
await client.email.envoyer({...});
}
Pièges courants (spécifiques à Node.js)
Voici les erreurs les plus fréquentes que les développeurs commettent lorsqu'ils intègrent une API d'envoi d'e-mails en JavaScript pour la première fois. Chacune est facile à éviter une fois que l'on connaît le schéma - et toutes s'appliquent également au contexte des API d'envoi d'e-mails dans Node.js.
await ne fonctionne qu'en modules ES.mjs ou "type":"module"Afin de pouvoir travailler avec JSON, vous devez généralement le charger dans une structure de données native. En JavaScript, cela signifie le convertir en objet.
Voici quelques fonctions que vous pouvez utiliser lorsque vous avez un fichier JSON :
* `JSON.parse()` : Cette méthode analyse une chaîne JSON et la convertit en objet JavaScript.
* `JSON.stringify()` : Cette méthode convertit un objet JavaScript en une chaîne JSON.
Vous pouvez également utiliser les deux fonctions pour envoyer des données à un autre serveur, ou pour obtenir des données d'un autre serveur. Par exemple :
```javascript
// Convertir un objet JavaScript en une chaîne JSON
const user = { name: "John Doe", age: 30 };
const jsonString = JSON.stringify(user);
// Analyser une chaîne JSON et la convertir en un objet JavaScript
const json = '{"name": "Jane Doe", "age": 25}';
const userObject = JSON.parse(json);
```
En CommonJS, encapsulez votre appel `send` dans un asynchrone IIFE ou utiliser .puis(). Le SDK fonctionne dans les deux – choisissez simplement le bon format de module.// CommonJS : encapsuler dans une IIFE asynchrone
(asynchrone () => {
const { UnipileClient } = attente import('unipile-node-sdk');
const client = nouveau UnipileClient(process.env.UNIPILE_DSN, process.env.UNIPILE_TOKEN);
await client.email.envoyer({ /* ... */ });
})();Promise.all enverra simultanément des erreurs de limite de débit et causera des erreurs 429. Utilisez un limiteur de concurrence comme p-limite pour plafonner les requêtes parallèles.import Pression limite from 'limite-p';
const limite = pLimite(5); // max 5 envois simultanés
const résultats = attente Promise.alldestinataires.carter => limite(() => client.email.envoyer({
account_id: process.env.EMAIL_ACCOUNT_ID,
à: [r], sujet, corps,
})))
);Tampon objet - pas une chaîne base64, pas une chaîne UTF-8. Si vous avez du contenu base64 (par exemple, provenant d'un webhook ou d'une réponse d'API), convertissez-le d'abord : Buffer.from(base64str, 'base64').// INCORRECT : passer une chaîne de caractères
pièces jointes : [['fichier.pdf', 'JVBERi0xLjQ...']] // chaîne base64 - casse !
// CORRECT: Objet tampon
pièces jointes : [['fichier.pdf', Tampon.from(chaîneBase64, base64)]]
// ou depuis le disque :
pièces jointes : [['fichier.pdf', await fs.lireFichier('./file.pdf')]]envoyer() l'appel fera planter le processus dans Node 15+. Toujours await le résultat ou joindre un .attrape() gestionnaire.// FAUX : à la volée - plante en cas d'erreur dans Node 15+
client.email.envoyer(charge utile); // pas d'await, pas de .catch()
// CORRECT : toujours gérer la promesse
await client.email.envoyer(charge utile) // option 1: attendre
.attraper(erreur => journal.erreur(err)) ; // option 2 : .catch()UNIPILE_TOKEN sont uniquement destinés au côté serveur Node.js. L'appel direct à l'API via le navigateur exposerait votre token. Utilisez une route backend (route API Next.js, endpoint Express, fonction Netlify/Vercel) comme proxy.account_id depuis un compte Gmail, Outlook ou IMAP précédemment lié. L'API renvoie 404 si l'account_id est manquant ou a été désactivé.Questions fréquemment posées
Questions courantes sur l'envoi d'e-mails en JavaScript et Node.js avec l'API unifiée de messagerie Unipile.
unipile-node-sdk, initialiser UnipileClient avec votre DSN et votre jeton, liez un compte Gmail ou Outlook via OAuth, puis appelez client.email.envoyer(). Pas de serveur SMTP, pas de port 587, pas de configuration TLS nécessaire de votre côté - Unipile gère la couche de transport.Non - et vous ne devriez pas. Appeler l'API Unipile à partir du JavaScript du navigateur exposerait votre UNIPILE_TOKEN à tout utilisateur qui ouvre DevTools. Appelez toujours l'API depuis un contexte Node.js côté serveur : une route Express, une route API Next.js (app/api/), une Vercel Edge Function ou une Netlify Function.
Votre frontend envoie une requête à votre propre point de terminaison backend, qui authentifie la session utilisateur puis appelle Unipile côté serveur.
Nodemailer se connecte directement à un serveur SMTP depuis votre processus Node.js. Il vous oblige à gérer vous-même les identifiants SMTP, à gérer le TLS, à configurer la DKIM, et à traiter séparément les particularités de chaque fournisseur.
L'API d'e-mail Unipile est une couche d'abstraction cloud : vous liez des comptes via OAuth (aucun identifiant SMTP requis pour Gmail/Outlook), obtenez un SDK unique et cohérent pour tous les fournisseurs, et Unipile gère le transport, les nouvelles tentatives et le rafraîchissement des jetons. Le compromis est que vos envois passent par l'infrastructure d'Unipile plutôt que par une connexion SMTP directe.
Oui. Le unipile-node-sdk package est livré avec des définitions de type TypeScript. Vous bénéficiez d'une complétion automatique et d'une sécurité de type complètes pour envoyer() charge utile, incluant Destinataire, options de suivi, et le type de réponse.
import { UnipileClient } from 'unipile-node-sdk';
// Types TS complets - l'autocomplétion fonctionne dans VSCode
const client : UnipileClient = nouveau UnipileClient(dsn, jeton);
const résultat = attente client.email.envoyer({ /* tapé! */ });Pour les envois à haut volume, utilisez un limiteur de concurrence (par exemple. p-limite avec 5 à 10 appels simultanés), ajoutez une politique de relance exponentielle en cas de réponses 429, et répartissez les envois sur plusieurs comptes liés si possible. Chaque compte de messagerie lié a ses propres limites d'envoi fixées par le fournisseur (Gmail : ~500/jour pour les comptes ordinaires, plus élevé pour Workspace).
Pour des envois en masse / marketing à grande échelle (millions de destinataires), envisagez un ESP dédié (Mailgun, SendGrid) en complément d'Unipile pour les envois transactionnels et basés sur OAuth.
Next.js : utiliser les routes APIapp/api/envoyer-email/route.js) ou Server Actions. Maintenez l'instanciation du SDK côté serveur uniquement.
Nuxt : use les routes serveur (server/api/send-email.post.ts. Le SDK est uniquement pour Node.js, il ne peut donc pas être inclus dans un composable ou un plugin qui s'exécute côté client.
NestJS: créer un ModuleEmail avec un service qui encapsule UnipileClient. Injectez-le partout où vous devez déclencher des envois - dans les contrôleurs, les tâches CRON ou les gestionnaires d'événements.
Vous avez encore des questions ? Notre équipe est là pour vous aider.