UNPKG

@email-service/email-service

Version:

email-service is a versatile npm package designed to simplify the integration and standardization of email communications across multiple Email Service Providers (ESPs).

106 lines (105 loc) 4.05 kB
import type { FromInput, StandardResponse } from './email.type.js'; import type { StandardError, ESPStandardizedError } from './error.type.js'; /** * Raison pour laquelle un email est inscrit dans la suppression list du * consommateur. * * - `hard_bounce` : l'adresse est invalide / n'existe pas. Blocage permanent, * non retirable. * - `spam_complaint` : le destinataire a marqué l'email comme spam. * - `unsubscribe_marketing` : le destinataire s'est désinscrit du canal * marketing (via lien List-Unsubscribe ou formulaire). Les transactionnels * restent autorisés. * - `unsubscribe_all` : désinscription totale, y compris transactionnels. */ export type SuppressionReason = 'hard_bounce' | 'spam_complaint' | 'unsubscribe_marketing' | 'unsubscribe_all'; /** * Stream d'envoi. Oriente le comportement (compliance, headers, règles de * suppression), pas la volumétrie. */ export type EmailStream = 'transactional' | 'marketing'; /** * Destinataire unitaire d'un envoi bulk. `mergeVars` permettent * l'interpolation `{{user.firstName}}` dans le subject/html/text via * `renderTemplate` de la lib. */ export type BulkRecipient = { email: string; name?: string; mergeVars?: Record<string, unknown>; }; /** * Template commun du batch. `text` est optionnel — s'il est absent, la lib * le dérive automatiquement de `html` via `stripHtml`. */ export type BulkTemplate = { subject: string; html: string; text?: string; }; /** * Hooks optionnels branchés sur l'instance `ESP`. Permettent au consommateur * d'implémenter sa suppression list / persistance sans que la lib connaisse * son storage. * * - `checkSuppression` : retourne une `SuppressionReason` si l'email doit être * skip, `null` sinon. La lib applique la règle (selon `stream`) au retour : * - transactional bloque sur `hard_bounce` et `unsubscribe_all` * - marketing bloque en plus sur `spam_complaint` et `unsubscribe_marketing` * Le consommateur peut simplifier en retournant toujours la reason brute — * la lib décide selon le stream si elle bloque ou non. * * - `onSent` / `onSkipped` / `onFailed` : notifications post-tentative. Le * consommateur les utilise typiquement pour alimenter une collection * `emailEvents` et agréger par `campaignId`. */ export type EmailServiceHooks = { checkSuppression?: (email: string, context: { stream: EmailStream; campaignId?: string; }) => Promise<SuppressionReason | null>; onSent?: (email: string, response: StandardResponse, campaignId?: string) => Promise<void>; onSkipped?: (email: string, reason: SuppressionReason, campaignId?: string) => Promise<void>; onFailed?: (email: string, error: StandardError | ESPStandardizedError, campaignId?: string) => Promise<void>; }; type BulkPayloadCommon = { campaignId: string; recipients: BulkRecipient[]; template: BulkTemplate; from: FromInput; metadata?: Record<string, unknown>; }; /** Payload bulk en mode transactionnel — pas d'unsubscribeUrl. */ export type BulkPayloadTransactional = BulkPayloadCommon & { stream: 'transactional'; }; /** * Payload bulk en mode marketing — `unsubscribeUrl` **obligatoire** et fourni * sous forme de fonction pour générer un URL par destinataire (one-click * typiquement avec un token distinct). */ export type BulkPayloadMarketing = BulkPayloadCommon & { stream: 'marketing'; unsubscribeUrl: (email: string) => string; }; export type BulkPayload = BulkPayloadTransactional | BulkPayloadMarketing; /** * Rapport synthétique retourné par `sendBulk`. Tout est en mémoire — la * persistance durable (events, stats campagne) se fait via les hooks. */ export type BulkReport = { campaignId: string; sent: number; skipped: Array<{ email: string; reason: SuppressionReason; }>; failed: Array<{ email: string; error: StandardError | ESPStandardizedError; }>; startedAt: string; endedAt: string; durationMs: number; }; export {};