# Invia email con Node.js

> Invia email da Node.js con l’SDK @emailit/node o con Nodemailer via SMTP, e verifica i webhook di Emailit in una route Express.

Questa guida mostra come inviare email da un’app Node.js con l’SDK ufficiale `@emailit/node`, come usare in alternativa Nodemailer via SMTP e come ricevere webhook firmati in Express.

## Prerequisiti

- Node.js 18 o versioni successive.
- Un [dominio di invio verificato](/it/docs/domains/add-a-domain/), ad esempio `acme.com`.
- Una [chiave API](/it/docs/developers/api-keys/). Per inviare basta una chiave di solo invio.
- Finché il workspace non ha l’[accesso alla produzione](/it/docs/workspaces/production-access/), puoi inviare solo agli indirizzi email degli account dei membri del workspace. Durante i test usa il tuo indirizzo.

## Installa l’SDK

```bash
npm install @emailit/node
```

Il pacchetto è solo ESM. Usa la sintassi `import`, oppure `await import('@emailit/node')` dal codice CommonJS.

## Configura la chiave API

Tieni la chiave fuori dal codice. Mettila in una variabile d’ambiente:

```bash title=".env"
EMAILIT_API_KEY=secret_••••••••••••••••••••••••••••••••
```

Carica il file con `node --env-file=.env` (Node.js 20.6 e versioni successive), con un pacchetto come `dotenv` o con le impostazioni dei secret della tua piattaforma. Aggiungi `.env` a `.gitignore`.

## Invia un’email

Crea un unico client e riutilizzalo tra le richieste:

```javascript title="send.mjs"

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_…
```

Eseguilo con `node --env-file=.env send.mjs`. L’email compare in **Email API → Emails** in pochi secondi.

In un’app Express, invia dalla route che genera l’email:

```javascript title="server.mjs"

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` accetta l’alias di un template o un ID `tem_`, e `variables` lo compila. Vedi [Template](/it/docs/templates/) e l’elenco completo dei campi in [Invia un’email](/it/docs/api-reference/emails/send/).

## Gestisci gli errori

L’SDK lancia errori tipizzati, così puoi reagire a ogni tipo di errore:

```javascript
  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;
  }
}
```

## Invia con SMTP

Se la tua app usa già [Nodemailer](https://nodemailer.com), indirizzalo all’SMTP relay di Emailit. Installalo con `npm install nodemailer`:

```javascript title="mailer.mjs"

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_…
```

Per la porta 465, imposta `port: 465` e `secure: true`. Se la tua rete blocca la 587, usa la 2525 o la 2587 con le stesse impostazioni. Vedi [Impostazioni SMTP](/it/docs/smtp/settings/).

## Ricevi i webhook

[Crea un webhook](/it/docs/webhooks/set-up/) che punta a `https://your-app.com/webhooks/emailit` e copia il suo secret di firma (`whsec_…`) in `EMAILIT_WEBHOOK_SECRET`.

Emailit firma ogni richiesta con un HMAC-SHA256 di `timestamp.rawBody`, quindi la route deve leggere il corpo grezzo. Su questa route usa `express.raw()`, non `express.json()`:

```javascript title="webhooks.mjs"

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);
}

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);
});
```

Monta il router con `app.use(webhooks)` prima di qualsiasi middleware globale `express.json()`. Restituisci un `2xx` entro 30 secondi; qualsiasi altra risposta viene ritentata. Per i dettagli, leggi [Firma delle richieste](/it/docs/webhooks/request-signature/) e [Nuovi tentativi ed errori](/it/docs/webhooks/retries-and-failures/).

## Consigli per la produzione

- **Limita il permesso della chiave.** Per il server dell’app usa una chiave di solo invio limitata al tuo dominio di invio. Riserva le chiavi con accesso completo agli script di amministrazione.
- **Resta entro il limite di frequenza.** Per impostazione predefinita, i nuovi workspace possono inviare 2 email al secondo e 5000 al giorno, condivise tra API e SMTP. Esegui gli invii massivi da una coda. Con Nodemailer, `pool: true, rateLimit: 2` mantiene un transport in pool a 2 messaggi al secondo. Vedi [Limiti e quote](/it/docs/limits/).
- **Rendi sicuri i nuovi tentativi.** Se ritenti un invio dopo un timeout, invia un header `Idempotency-Key` così Emailit non invia due volte. L’SDK non imposta header personalizzati, quindi per queste chiamate usa `fetch`; vedi [Idempotenza](/it/docs/email-api/idempotency/).
- **Elabora i webhook in modo idempotente.** Salva ogni `event_id` che hai gestito e salta i duplicati, ed esegui il lavoro lento in un job in background dopo aver restituito `200`.
- **Usi TypeScript?** L’SDK non ha ancora dichiarazioni di tipo. Aggiungi `declare module '@emailit/node';` a un file `.d.ts` nel tuo progetto.

## Passaggi successivi

  - [Invia email con l’API](/it/docs/email-api/send-email/): Allegati, programmazione, tracciamento e metadati.
  - [Tipi di evento dei webhook](/it/docs/webhooks/event-types/): Ogni evento e il suo payload.
  - [Next.js](/it/docs/frameworks/nextjs/): Route handler e server action.
  - [SDK e librerie](/it/docs/sdks/): Tutte le librerie ufficiali.

---
Fonte: https://emailit.com/it/docs/frameworks/nodejs/
