sending-sdk
v0.5.0
Published
SDK TypeScript ufficiale per l'API di Sending.dev
Maintainers
Readme
sending-sdk
SDK TypeScript ufficiale per l'API di Sending.dev (email + WhatsApp + Telegram).
I tipi sono generati dallo spec OpenAPI, il client e' scritto a mano per la migliore DX.
Installazione
npm install sending-sdk
# pnpm add sending-sdk · yarn add sending-sdkRichiede Node.js >= 18 (usa fetch nativo).
Uso
import { Sending } from "sending-sdk";
const sending = new Sending({ apiKey: process.env.SENDING_API_KEY! });
// Email transazionale
await sending.emails.send({
to: "[email protected]",
from: "[email protected]",
subject: "Benvenuto",
html: "<p>Ciao!</p>",
idempotencyKey: "welcome-001",
});
// Messaggio multi-canale
await sending.messages.send({
channel: "whatsapp",
to: "+393331234567",
text: "Ciao!",
idempotencyKey: "wa-001",
});Invio batch
Fino a 100 email in una richiesta, che ai fini del rate limit ne vale una. L'esito e'
parziale: results e' allineato per indice alla lista passata, quindi un elemento fallito
non impedisce gli altri, e un duplicato idempotente torna accepted con duplicate: true.
const esito = await sending.emails.sendBatch([
{ from: "Acme <[email protected]>", to: "[email protected]", subject: "Ciao", html: "<p>hey</p>", idempotencyKey: "b-001" },
{ from: "Acme <[email protected]>", to: "[email protected]", subject: "Ciao", html: "<p>hey</p>", idempotencyKey: "b-002" },
]);
for (const r of esito.results) {
if (r.status === "failed") console.error(`elemento ${r.index}: ${r.error?.code}`);
}Copie visibili e nascoste
cc e bcc valgono su emails.send, emails.sendBatch, messages.send (canale email) e
sugli invii dalle inbox agente. Massimo 50 destinatari per messaggio, e ogni destinatario
consuma una unita' di quota.
await sending.emails.send({
from: "Acme <[email protected]>",
to: "[email protected]",
cc: ["[email protected]"],
bcc: ["[email protected]"],
subject: "Preventivo",
html: "<p>In allegato.</p>",
idempotencyKey: "prev-001",
});Allegati
Un allegato si carica una volta e si riusa su piu' invii: passa attachments: [{ id }] a emails.send, messages.send, campaigns.create e agli invii dalle inbox agente.
// File di qualsiasi dimensione: create + PUT firmato + confirm, in un metodo.
const doc = await sending.attachments.upload({
filename: "fattura.pdf",
data: bytes, // Uint8Array | ArrayBuffer | Blob
contentType: "application/pdf",
});
await sending.emails.send({
to: "[email protected]",
from: "[email protected]",
subject: "La tua fattura",
html: "<p>In allegato la fattura.</p>",
attachments: [{ id: doc.id }],
idempotencyKey: "fattura-001",
});In alternativa all'id puoi passare il file inline ({ filename, content } in base64) o una URL pubblica ({ filename, url }). Con contentId l'allegato diventa inline e lo referenzi nell'HTML come cid:.
Limiti: 20 allegati per messaggio, 10 MB l'uno, 25 MB complessivi. Le estensioni eseguibili sono rifiutate.
Contatti e paginazione
const page = await sending.contacts.list({ q: "mario", page: 1, pageSize: 50 });
console.log(page.total, page.data);
// Idempotente sull'identita': se il contatto c'e' gia' lo aggancia e torna `created: false`.
const { id, created } = await sending.contacts.create({
attributes: { firstName: "Mario" },
identities: [{ channel: "email", address: "[email protected]", consent: "opted_in" }],
});
await sending.contacts.addTag(id, "<tag-uuid>");
const contatto = await sending.contacts.get(id);
await sending.contacts.delete(id);Vale anche per lists.create e tags.create, idempotenti sul nome: non serve cercare prima di scrivere, e ripetere la stessa richiesta non crea doppioni. Gli attributi si fondono (null cancella la chiave) e il consenso viene toccato solo se lo dichiari, cosi un payload che tace non azzera un opt-in raccolto altrove.
Gestione errori
import { SendingError } from "sending-sdk";
try {
await sending.emails.send({ /* ... */ } as any);
} catch (err) {
if (err instanceof SendingError) {
console.error(err.status, err.code, err.body);
}
}Configurazione
new Sending({
apiKey: "sk_...", // richiesta
baseUrl: "https://...", // opzionale, default produzione
fetch: customFetch, // opzionale (test/polyfill)
});Risorse disponibili
emails · messages · events · attachments · campaigns · contacts · lists ·
tags · customFields · segments · domains · inboxes · emailRules ·
automations · webhooks · utm · integrations · usage.
Autenticazione e scope
La key (sk_...) determina i permessi (scope). Vedi la
reference interattiva per gli scope per endpoint.
Sviluppo
pnpm gen # rigenera src/generated/types.ts da openapi.json
pnpm build # bundle ESM + CJS + d.ts (tsup)
pnpm test # vitestLo openapi.json viene copiato qui da pnpm openapi:generate (package @sending/openapi).
