Connessioni
Le connessioni sono i canali verso servizi esterni: SMTP per inviare email, caselle IMAP per riceverle, e i provider di fatturazione elettronica. I segreti sono cifrati a riposo.
Creare e modificare connessioni richiede il ruolo amministratore. Fa eccezione
GET /connections/senders, accessibile agli utenti autenticati
per sapere da quali mittenti possono inviare.
01Endpoint
| Metodo | Path | Cosa fa | |
|---|---|---|---|
| GET | /api/connections/senders | auth | Mittenti email utilizzabili (nessun segreto). |
| GET | /api/connections | admin | Elenco connessioni. |
| GET | /api/connections/:id | admin | Una connessione (senza segreti in chiaro). |
| POST | /api/connections | admin | Crea una connessione. |
| PATCH | /api/connections/:id | admin | Modifica parziale. |
| DELETE | /api/connections/:id | admin | Elimina. |
| POST | /api/connections/:id/test | admin | Invio di prova per validare una connessione email. |
02L'oggetto Connessione
La lettura di una connessione restituisce la forma sanificata: i metadati e la
config non sensibile, mai il segreto. La presenza di una credenziale è segnalata dal solo
flag hasSecret.
| Attributo | Tipo | Descrizione |
|---|---|---|
| id | integer | Identificativo della connessione. |
| channel | string | Tipo di canale: email, mailbox o billing. |
| name | string | Nome descrittivo. 1–120 caratteri. |
| config | object | Impostazioni non sensibili del canale (host, porta, mittente, provider…). Vedi Tipi di connessione. |
| isActive | boolean | Se la connessione è utilizzabile. Default true. |
| hasSecret | boolean | true se è memorizzata una credenziale cifrata. Il segreto non viene mai restituito. |
| createdBy | integer | null | Utente che l'ha creata. |
| updatedBy | integer | null | Ultimo utente che l'ha modificata. |
| createdAt | string | Data/ora di creazione (ISO 8601). |
| updatedAt | string | Data/ora ultima modifica (ISO 8601). |
{ "id": 4, "channel": "email", "name": "Mittente commerciale", "config": { "fromName": "Acme Vendite", "fromEmail": "vendite@acme.it", "smtpHost": "smtp.acme.it", "smtpPort": 587, "secure": false, "username": "vendite@acme.it" }, "isActive": true, "hasSecret": true, "createdBy": 7, "updatedBy": 7, "createdAt": "2026-07-07T15:24:00.000Z", "updatedAt": "2026-07-07T15:24:00.000Z" }
Il segreto (password SMTP/IMAP, API key del provider) è cifrato a riposo con AES-256-GCM e
non torna mai in chiaro nelle risposte: la config espone solo username,
non la password. La sua presenza è indicata dal solo hasSecret. Le
connessioni si configurano solo su canale cifrato (HTTPS).
03Tipi di connessione
Il campo channel (default email) determina
quali campi config sono richiesti. In creazione i campi di config
possono stare al livello superiore del body o dentro un oggetto config.
Email in uscita (SMTP) · channel: "email"
| Campo config | Tipo | Note | |
|---|---|---|---|
| fromEmail | string | richiesto | Indirizzo mittente, validato. Max 200. |
| fromName | string | opzionale | Nome visualizzato. Max 120. |
| smtpHost | string | richiesto | Host del server SMTP. Max 200. |
| smtpPort | integer | richiesto | Porta 1–65535 (es. 587, o 465 con secure). |
| username | string | richiesto | Utente SMTP. Max 200. |
| secure | boolean | opzionale | TLS implicito. Default true sulla porta 465. |
La password va nel campo secret del body (vedi Creare),
non nella config.
Casella in ingresso (IMAP) · channel: "mailbox"
| Campo config | Tipo | Note | |
|---|---|---|---|
| imapHost | string | richiesto | Host del server IMAP. Max 200. |
| imapPort | integer | opzionale | Porta 1–65535. Default 993. |
| username | string | richiesto | Utente della casella. Max 200. |
| secure | boolean | opzionale | TLS implicito. Default true sulla porta 993. |
| folder | string | opzionale | Cartella da leggere. Default INBOX. |
La casella viene interrogata dal worker per importare le email ricevute e collegarle a contatto/lead/account in base al mittente.
Fatturazione elettronica · channel: "billing"
| Campo config | Tipo | Note | |
|---|---|---|---|
| provider | string | richiesto | Uno tra fattureincloud, fattura24, openapi. |
| companyId | string | condizionale | Richiesto per fattureincloud (multi-azienda). Max 40. |
| environment | string | opzionale | Solo per openapi: sandbox (default) o production. |
La API key / access token del provider va nel campo secret del body.
04Elencare i mittenti
Accessibile a ogni utente autenticato: elenca le connessioni email attive da cui può inviare. Restituisce solo id, nome e mittente: nessuna config, nessun segreto.
Richiestacurl "https://crm.tuodominio.it/api/connections/senders" \ -H "Authorization: Bearer <accessToken>"
const res = await fetch("https://crm.tuodominio.it/api/connections/senders", { headers: { Authorization: `Bearer ${accessToken}` }, }); const { data } = await res.json();
{ "success": true, "data": { "items": [ { "id": 4, "name": "Mittente commerciale", "fromEmail": "vendite@acme.it" } ] } }
05Elencare le connessioni
Elenco completo per gli amministratori, in forma sanificata.
Parametri query| Parametro | Tipo | Descrizione | |
|---|---|---|---|
| channel | string | opzionale | Filtra per canale: email, mailbox, billing. |
curl "https://crm.tuodominio.it/api/connections?channel=email" \ -H "Authorization: Bearer <accessToken>"
const res = await fetch("https://crm.tuodominio.it/api/connections?channel=email", { headers: { Authorization: `Bearer ${accessToken}` }, }); const { data } = await res.json();
{ "success": true, "data": { "items": [ { "id": 4, "channel": "email", "hasSecret": true, … } ] } }
06Creare una connessione
| Campo | Tipo | Note | |
|---|---|---|---|
| channel | string | opzionale | email (default), mailbox o billing. |
| name | string | richiesto | Nome descrittivo. 1–120 caratteri. |
| secret | string | richiesto | Password / token. Cifrato a riposo, mai restituito. Max 2000. |
| config… | object | richiesto | Campi del canale scelto: vedi Tipi di connessione. In creazione possono stare al livello superiore del body. |
| isActive | boolean | opzionale | Default true. |
curl -X POST https://crm.tuodominio.it/api/connections \ -H "Authorization: Bearer <accessToken>" \ -H "Content-Type: application/json" \ -d '{ "channel": "email", "name": "Mittente commerciale", "fromEmail": "vendite@acme.it", "fromName": "Acme Vendite", "smtpHost": "smtp.acme.it", "smtpPort": 587, "username": "vendite@acme.it", "secret": "super-secret-password" }'
const res = await fetch("https://crm.tuodominio.it/api/connections", { method: "POST", headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json", }, body: JSON.stringify({ channel: "email", name: "Mittente commerciale", fromEmail: "vendite@acme.it", fromName: "Acme Vendite", smtpHost: "smtp.acme.it", smtpPort: 587, username: "vendite@acme.it", secret: "super-secret-password", }), }); const { data } = await res.json();
{ "success": true, "data": { "item": { "id": 4, "channel": "email", "hasSecret": true, … } } }
| Stato | Codice | Quando |
|---|---|---|
| 201 | · | Connessione creata; nel corpo l'oggetto sanificato. |
| 401 | UNAUTHORIZED | Token assente o non valido. |
| 403 | FORBIDDEN | Utente non amministratore. |
| 422 | VALIDATION_ERROR | Canale non ammesso, secret mancante, email non valida, porta fuori range o cifratura non configurata. |
07Modificare ed eliminare
Modifica parziale: invia solo i campi da cambiare (almeno uno). I campi di
config vengono sostituiti in blocco quando ne è presente almeno uno. Il
secret viene aggiornato solo se ne fornisci uno non vuoto,
altrimenti resta invariato. Risponde 200 con l'oggetto aggiornato,
404 se inesistente, 422 se non passi
alcun campo valido.
Elimina la connessione. Risponde 200 { id },
404 se inesistente.
08Invio di prova
Valida una connessione email inviando un messaggio di prova. Body:
{ "to": "verifica@acme.it" }. Con esito positivo risponde
200 { sent: true, messageId }; una
config SMTP errata è un esito atteso e torna 422
CONNECTION_TEST_FAILED con il motivo, non un 500.