Come Inviare e-mail tramite API in JavaScript (Tutorial Node.js)
Salta il boilerplate SMTP. Questa guida mostra come inviare email in Node.js utilizzando il API di posta elettronica unificata Unipile - con codice copia-incolla per Gmail, Outlook e SMTP in meno di 10 righe di JavaScript.
import {UnipileClient } from 'unipile-node-sdk';
const client = nuovo UnipileClient(
process.env.UNIPILE_DSN,
process.env.UNIPILE_TOKEN
);
await client.email.inviare({
account_id: 'IL_TUO_ID_ACCOUNT',
a: [{ nome_visualizzato: 'Alice',
identificatore: 'alice@example.com' }],
oggetto: 'Ciao da Node.js',
body: 'Inviato tramite Unipile!
'
});Esempio Node.js a 5 righe
Se sai già cosa è un Invio di e-mail API è e voglio solo inviare codice API JavaScript per email che funzioni davvero, eccolo. Il tutorial completo segue qui sotto.
npm installare unipile-node-sdkUNIPILE_DSN e UNIPILE_TOKEN al tuo .env file.client.email.invia()account_id, a, soggetto, e corpo. Fatto.import {UnipileClient } from 'unipile-node-sdk';
const client = nuovo UnipileClient(
process.env.UNIPILE_DSN,
process.env.UNIPILE_TOKEN
);
const risultato = attendere client.email.inviare({
account_id: 'acc_xxxxxxxxxxxxxxxx',
a: [{
nome_visualizzato: 'Alice Martin',
identificatore: 'alice@acme.com'
}],
oggetto: 'Ciao da Node.js',
body: 'Inviato tramite API Unipile!
'
});
console.log(risultato); // { tracking_id: 'msg_...' }Prerequisiti e configurazione
Prima di poter utilizzare il flusso di lavoro API JavaScript di invio e-mail in produzione, sono necessari quattro elementi: una versione di Node.js supportata, l'SDK Unipile, una chiave API e un endpoint DSN.
fetch e di primo livello await. Si consiglia la versione LTS di Node 20 per la produzione. Verifica la tua versione con node -v.api4.unipile.com:13444Entrambi sono necessari per inizializzare il client..mjs file o impostare "tipo":"modulo" in package.json. Per CommonJS, dinamico import() funziona anche - esempi mostrati di seguito.npm installare unipile-node-sdkyarn add unipile-node-sdkpnpm add unipile-node-sdk# Credenziali Unipile (non effettuare mai il commit di questo file)
UNIPILE_DSN=https://api4.unipile.com:13444
UNIPILE_TOKEN=il_tuo_token_di_accesso_qui
# L'ID dell'account del servizio email collegato
EMAIL_ACCOUNT_ID=acc_xxxxxxxxxxxxxxxxAggiungi .env al tuo .gitignore. Usa dotenv o la nativa Node 20.6+ --file-ambiente bandiera per caricarla node --env-file=.env send.mjs.
Collegamento del tuo primo account email
Il API email unificata usa un singolo account_id per astrarre le differenze tra i provider. Collega un account una volta, quindi chiama client.email.invia() identicamente attraverso tutti e tre i fornitori.
Scegli il tuo provider qui sotto per vedere lo snippet Node.js esatto. L'account_id restituito è quello che salvi e riutilizzi per ogni invio successivo.
import {UnipileClient } from 'unipile-node-sdk';
const client = nuovo UnipileClient(process.env.UNIPILE_DSN, process.env.UNIPILE_TOKEN);
// Passo 1: genera un link OAuth ospitato per Gmail
const { url } = attendere client.account.createHostedAuthLink({
type: 'GOOGLE',
url_reindirizzamento_successo: process.env.OAUTH_CALLBACK_URL,
failure_redirect_url: process.env.OAUTH_CALLBACK_URL + '?errore=1',
});
// Passaggio 2: reindirizza il tuo utente a `url`
console.log('Reindirizza l'utente a:', url);
// Passaggio 3: Unipile invia l'account_id alla tua callback
// Memorizzala: process.env.EMAIL_ACCOUNT_ID = result.account_idimport {UnipileClient } from 'unipile-node-sdk';
const client = nuovo UnipileClient(process.env.UNIPILE_DSN, process.env.UNIPILE_TOKEN);
// Funziona per Outlook personale E Microsoft 365 / Exchange Online
const { url } = attendere client.account.createHostedAuthLink({
type: 'MICROSOFT',
url_reindirizzamento_successo: process.env.OAUTH_CALLBACK_URL,
failure_redirect_url: process.env.OAUTH_CALLBACK_URL + '?errore=1',
});
// Reindirizza l'utente -> completano il flusso OAuth di Microsoft
console.log('Reindirizza l'utente a:', url);
// Vedi: /syncing-emails-with-microsoft-graph-api-a-developers-guide/import {UnipileClient } from 'unipile-node-sdk';
const client = nuovo UnipileClient(process.env.UNIPILE_DSN, process.env.UNIPILE_TOKEN);
// SMTP/IMAP: passa le credenziali direttamente (nessun reindirizzamento OAuth)
const account = attendere client.account.create({
type: 'IMAP',
imap: {
username: process.env.IMAP_UTENTE,
password: process.env.IMAP_PASS, host: process.env.IMAP_HOST,
porta: 993,
},
smtp: {
username: process.env.IMAP_UTENTE,
password: process.env.IMAP_PASS, host: process.env.SMTP_HOST,
porta: 587,
},
});
console.log(account.account_id); // memorizza questoInviare la tua prima email da Node.js
Tre pattern pronti per la produzione per il flusso di lavoro JavaScript dell'API di invio email: testo normale, HTML con CC/BCC e lettura dell'oggetto response. Tutti utilizzano lo stesso client.email.invia() chiamata.
import {UnipileClient } from 'unipile-node-sdk';
const client = nuovo UnipileClient(process.env.UNIPILE_DSN, process.env.UNIPILE_TOKEN);
const risultato = attendere client.email.inviare({
account_id: process.env.EMAIL_ACCOUNT_ID,
a: [{ nome_visualizzato: 'Bob', identificatore: 'bob@example.com' }],
oggetto: 'Benvenuti sulla piattaforma',
body: 'Ciao Bob, il tuo account è pronto.',
});
console.log(result.id_tracciamento); // msg_xxxxxxxxxxxxxxxxconst risultato = attendere client.email.inviare({
account_id: process.env.EMAIL_ACCOUNT_ID,
a: [{ display_name: 'Alice', identificatore: 'alice@acme.com' }],
cc: [{ nome_visualizzato: 'Gestore', identificatore: 'boss@acme.com' }],
bcc: [{ display_name: 'Revisione', identificatore: 'audit@internal.io' },
oggetto: 'La tua fattura #1042',
// corpo HTML - il provider lo renderizza nativamente
body: `
Fattura #1042
Importo dovuto: $299
Paga ora
`,
});
console.log('Sent:', risultato.tracking_id);| Campo | Tipo | Richiesto | Descrizione |
|---|---|---|---|
account_id | stringa | Richiesto | ID dell'account email collegato da cui inviare |
a | Destinatario[] | Richiesto | Array di {nome_visualizzato, identificatore} oggetti |
soggetto | stringa | Richiesto | Oggetto dell'email |
corpo | stringa | Richiesto | Testo normale o stringa HTML |
cc | Destinatario[] | Opzionale | Destinatari in copia carbone |
DCC | Destinatario[] | Opzionale | Destinatari in copia conoscenza nascosta |
from | Destinatario | Opzionale | Sovrascrivi nome visualizzato mittente |
risposta_a | stringa | Opzionale | ID del messaggio del provider a cui rispondere (thread) |
allegati | Array | Opzionale | Array di [nomefile, Buffer] tuple |
intestazioni_personalizzate | oggetto[] | Opzionale | Array di intestazioni X personalizzate |
opzioni_di_tracciamento | oggetto | Opzionale | {apre, collega, etichetta} - abilita il tracciamento di aperture/clic |
Ottieni la tua chiave API, collega un account Gmail o Outlook in pochi minuti ed esegui gli esempi Node.js di questa guida su caselle di posta reali.
Invio di allegati in Node.js
Il allegati campo accetta un array di [nomefile, Buffer] tuple. Leggi il file con Node fs.readFileSync oppure trasmettilo in streaming con fs.promises.readFile.
fs.promises.readFile(percorso) per ottenere un Buffer, quindi passare ['nomefile.pdf', buffer]. Funziona per PDF, DOCX, immagini, qualsiasi file binario.cid: schema. Fai riferimento allo stesso nome del file usato nella tupla degli allegati: <img src="cid:logo.png">.pdfkit), raccoglilo in un Buffer e allegalo senza scrivere su disco. Sicuro per la produzione in ambienti serverless.import {UnipileClient } from 'unipile-node-sdk';
import promesse come fs from 'nodo:fs';
const client = nuovo UnipileClient(process.env.UNIPILE_DSN, process.env.UNIPILE_TOKEN);
// Leggi file in un Buffer
const pdfBuffer = attendere fs.leggiFile('./fattura.pdf');
await client.email.inviare({
account_id: process.env.EMAIL_ACCOUNT_ID,
a: [{ display_name: 'Cliente', identificatore: 'client@example.com' }],
oggetto: 'La tua fattura è allegata',
body: 'Si prega di trovare la Vostra fattura in allegato.
',
allegati: [
['fattura.pdf', pdfBuffer], // [nomefile, Buffer]
],
});const [logo, rapporto] = attendere Promise.all([
fs.leggiFile('./logo.png'),
fs.leggiFile('./report.xlsx'),
]);
await client.email.inviare({
account_id: process.env.EMAIL_ACCOUNT_ID,
a: [{ nome_visualizzato: 'Squadra', identificatore: 'team@acme.com' }],
oggetto: 'Rapporto Q1',
body:
Rapporto Q1
Vedere il foglio di calcolo allegato per i dettagli.
`,
allegati: [
['logo.png', logo], // inline tramite cid:logo.png nel corpo
['report.xlsx', rapporto], // allegato normale
],
});Risposte, Thread e Monitoraggio
Andare oltre i semplici invii: risposte di thread, intestazioni personalizzate per l'idempotenza, tracciamento di apertura/clic tramite webhook, e invio email per conto di un utente.
1
Rispondendo a un thread
Passa l'ID del messaggio del provider (restituito nella risposta di invio originale o dall'elenco delle email) come risposta_a. Unipile inietta il corretto In-Reply-To e Riferimenti intestazioni in modo che le risposte vengano indirizzate correttamente in Gmail, Outlook e client IMAP.
await client.email.inviare({
account_id: process.env.EMAIL_ACCOUNT_ID,
a: [{ nome_visualizzato: 'Alice', identificatore: 'alice@acme.com' }],
oggetto: 'Re: La tua domanda',
body: 'Grazie per avermi contattato! Ecco la risposta...
',
// ID del messaggio del provider dall'email originale
rispondi_a: 'msg_xxxxxxxxxxxxxxxx',
});
2
Intestazioni personalizzate e idempotenza
Utilizzo intestazioni_personalizzate per aggiungere qualsiasi cosa X- header. Un modello comune è Chiave-X-Idempotenza per evitare invii duplicati in caso di ritentativo dopo un timeout di rete.
import { uuid_casuale } from 'nodo:crypto';
await client.email.inviare({
account_id: process.env.EMAIL_ACCOUNT_ID,
a: [{ nome_visualizzato: 'Bob', identificatore: 'bob@example.com' }],
oggetto: 'Conferma d'ordine #9981',
body: 'Il tuo ordine è confermato.
',
custom_headers: [
{ name: 'X-Idempotency-Key', valore: UUIDCasuale},
{ nome: 'ID Ordine X', valore: '9981' },
],
});
3
Monitoraggio aperture e clic tramite webhook
Abilita il tracciamento in opzioni_di_tracciamento. Unipile invia un evento webhook (email.aperta / email.link_cliccato) al tuo URL webhook registrato con il etichetta ti sei impostato qui in modo da poter correlare gli eventi ai tuoi ID interni.
await client.email.inviare({
account_id: process.env.EMAIL_ACCOUNT_ID,
a: [{ nome_visualizzato: 'Piombo', identificatore: 'lead@prospect.com' }],
oggetto: 'In seguito alla tua prova',
body: 'Ciao, volevo fare un controllo...
',
tracking_options: {
aperture: true, // attiva il webhook email.opened
link: true, // Invia il webhook di email.link_clicked
etichetta: 'crm_lead_12345', // il tuo ID di correlazione interno
},
});
4
Invio per conto di un altro utente
Quando si creano applicazioni SaaS multi-tenant, ogni utente finale collega il proprio account e-mail. Conservare account_id per utente nel tuo database e passalo al momento dell'invio. Vedi la guida completa su come inviare un'email per conto di un utente.
// Ogni utente ha il proprio account_id collegato memorizzato nel tuo DB
async function inviaComeUtente(userId, a, oggetto, corpo) {
const utente = attendere db.OttieniUtente(userId);
return client.email.inviareaccount_id: user.unipile_account_id, // per-utente
a, oggetto, corpo,
});
}
// L'e-mail viene inviata dall'account Gmail di Alice, non dal tuo indirizzo del server
await inviaComeUtente('utente_alice', destinatari, oggetto, corpo);Lavori con Python? Vedi il nostro Implementazione Python guida.
Gestione degli Errori e Riprova
I malfunzionamenti della rete e i limiti di velocità sono inevitabili su larga scala. Ecco un pattern di produzione async/await per la tua implementazione JavaScript dell'API di invio email, con backoff esponenziale e logging strutturato utilizzando Winston o Pino.
tracking_id è popolata. Nessun ritentativo necessario.Ritenta dopo intestazione. Usa il backoff esponenziale.UNIPILE_TOKEN Variabile d'ambiente. Non riprovare: correggi le credenziali.account_id non esiste o è stato revocato. Riconnetti l'account.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.
',
});Migliori pratiche di sicurezza in Node.js
Tuo UNIPILE_TOKEN concede accesso API completo. Non esporlo mai lato client. Vedi il completo guida alla sicurezza delle API via email per argomenti avanzati tra cui DKIM, SPF e rotazione dei token OAuth.
UNIPILE_TOKEN deve rimanere sul server. Qualsiasi JavaScript lato browser - inclusi i componenti client di Next.js, il frontend React o Vite - NON deve importare direttamente il token./api/invia-emailIn Express, un endpoint POST. Autentica i tuoi utenti prima, poi chiama il server Unipile con il token dall'ambiente.account_id rimane valido. Non è necessario gestire la scadenza del token di accesso in autonomia.// client.js - MAI fare questo
const client = new UnipileClient(
'https://api4.unipile.com:13444',
'sk_live_xxxxxxxxxx' Smascherato!
);
// app/api/send-email/route.js
esporta asincrono funzione POST(req) {
// controlla prima l'autenticazione
const session = await getServerSession();
if (!session) return new Response(null,{status:401});
const client = new UnipileClient(
process.env.UNIPILE_DSN, // solo server
process.env.UNIPILE_TOKEN // solo server
);
await client.email.send({...});
}
Errori comuni (specifici di Node.js)
Questi sono gli errori più frequenti commessi dagli sviluppatori quando integrano un'API di invio email in JavaScript per la prima volta. Ciascuno è facile da evitare una volta che si conosce lo schema, e tutti valgono anche nel contesto dell'API di invio email di Node.js.
await funziona solo in moduli ES.mjs o "tipo":"modulo"In CommonJS, racchiudi la tua chiamata send in un asincrono IIFE o usa .allora(). L'SDK funziona in entrambi: scegli semplicemente il formato del modulo giusto.// CommonJS: incorpora in IIFE asincrona
(async () => {
const {UnipileClient } = attendere import('unipile-node-sdk');
const client = nuovo UnipileClient(process.env.UNIPILE_DSN, process.env.UNIPILE_TOKEN);
await client.email.inviare({ /* ... */ });
})();Promise.all invii simultaneamente raggiungeranno i limiti di velocità e causeranno errori 429. Usa un limitatore di concorrenza come p-limite per limitare le richieste parallele.import pLimite from 'p-limite';
const limite = pLimite(5); // invii concorrenti max 5
const risultati = attendere Promise.alldestinatari.mappa(r => limite(() => client.email.inviareaccount_id: process.env.EMAIL_ACCOUNT_ID,
a: [r], oggetto, corpo,
})))
);Buffer oggetto - non una stringa base64, non una stringa UTF-8. Se hai contenuto base64 (ad esempio da un webhook o una risposta API), convertilo prima: Buffer.from(base64str, 'base64').// SBAGLIATO: passaggio di una stringa
Allegati: [['file.pdf', 'JVBERi0xLjQ...']] // stringa base64 - si blocca!
// CORRETTO: Oggetto buffer
Allegati: [['file.pdf', Buffer.from(stringa_base64, 'base64')]]
// o dal disco:
Allegati: [['file.pdf', await fs.leggiFile('./file.pdf')]]invia() La chiamata bloccherà il processo in Node 15+. Sempre await il risultato o allegare un .catch() gestore.// SBAGLIATO: fire-and-forget - va in crash con errori in Node 15+
client.email.inviare(carico utile); // non await, non .catch()
// CORRETTO: gestisci sempre la promise
await client.email.inviare(payload) // opzione 1: await
.catturaErrore => registratore.errore(err)); // opzione 2: .catch()UNIPILE_TOKEN sono solo per Node.js lato server. L'accesso diretto all'API dal browser esporrebbe il tuo token. Usa una route backend (route API di Next.js, endpoint Express, funzione Netlify/Vercel) come proxy.account_id da un account Gmail, Outlook o IMAP collegato in precedenza. L'API restituisce 404 se l'ID account non è presente o è stato scollegato.Domande frequenti
Domande frequenti sull'invio di e-mail in JavaScript e Node.js con l'API unificata per le e-mail di Unipile.
unipile-node-sdk, inizializzare UnipileClient Con il tuo DSN e token, collega un account Gmail o Outlook tramite OAuth, quindi chiama client.email.invia(). Nessun server SMTP, nessuna porta 587, nessuna configurazione TLS necessaria da parte tua: Unipile gestisce il livello di trasporto.No, e non dovresti farlo. Chiamare l'API Unipile da JavaScript nel browser esporrebbe il tuo UNIPILE_TOKEN a qualsiasi utente che apre DevTools. Chiama sempre l'API da un contesto Node.js lato server: una route Express, una route API di Next.js (app/api/), una Vercel Edge Function o una Netlify Function.
Il tuo frontend invia una richiesta al tuo endpoint backend, che autentica la sessione dell'utente e quindi chiama Unipile lato server.
Nodemailer si connette direttamente a un server SMTP dal tuo processo Node.js. Richiede la gestione delle credenziali SMTP, la gestione di TLS, la configurazione di DKIM da soli e la gestione delle peculiarità di ogni provider separatamente.
L'API email di Unipile è uno strato di astrazione cloud: colleghi account tramite OAuth (nessuna credenziale SMTP necessaria per Gmail/Outlook), ottieni un SDK unico e coerente per tutti i provider, e Unipile gestisce il trasporto, i tentativi e il refresh dei token. Il compromesso è che i tuoi invii passano attraverso l'infrastruttura di Unipile invece che tramite una connessione SMTP diretta.
Sì. Il unipile-node-sdk pacchetto include definizioni di tipo TypeScript. Ottieni completamento automatico completo e sicurezza dei tipi per invia() payload, incluso Destinatario, opzioni_di_tracciamento, e il tipo di risposta.
import {UnipileClient } from 'unipile-node-sdk';
// Tipi TS completi - l'autocompletamento funziona in VSCode
const cliente: UnipileClient = nuovo UnipileClient(dsn, token);
const risultato = attendere client.email.inviare({ /* digitato! */ });Per invii ad alto volume, utilizzare un limitatore di concorrenza (ad esempio. p-limite con 5-10 chiamate concorrenti), aggiungere un backoff esponenziale alle risposte 429 e distribuire gli invii su più account collegati, se possibile. Ciascun account email collegato ha i propri limiti di invio impostati dal provider (Gmail: ~500/giorno per account normali, più alti per Workspace).
Per invii di massa/marketing su larga scala (milioni di destinatari), prendi in considerazione un ESP dedicato (Mailgun, SendGrid) insieme a Unipile per invii transazionali e basati su OAuth.
Next.js: usa route API (app/api/invia-email/route.js) o Server Actions. Mantieni l'istanza dell'SDK solo lato server.
Nuxt: usa route del serverserver/api/send-email.post.tsL'SDK è solo per Node.js, quindi non può essere inserito in un componente componibile o in un plugin che viene eseguito sul client.
NestJS: crea un ModuloEmail con un servizio che avvolge UnipileClient. Inseriscilo ovunque sia necessario attivare gli invii: nei controller, nei processi CRON o negli handler di eventi.
Avete ancora domande? Il nostro team è qui per aiutarvi.