### Route Construction Example Source: https://email-sdk.dev/docs/concepts/fallbacks-and-retries.md Illustrates the order of adapters used for sending an email, starting with the selected adapter followed by fallbacks. Duplicate names are removed. ```txt [adapter, ...fallbackAdapters] ``` -------------------------------- ### Verify Email SDK Installation and Adapters Source: https://email-sdk.dev/docs/getting-started/install.md Verify the SDK installation and list supported providers along with their required environment variables using the CLI. ```bash npx email-sdk version npx email-sdk adapters ``` -------------------------------- ### Run Email SDK CLI (Installed Project) Source: https://email-sdk.dev/docs/getting-started/install.md Execute the email-sdk CLI commands after installing the package in your project. This is used to list adapters or perform other CLI operations. ```bash npx email-sdk adapters ``` -------------------------------- ### Package Structure Example Source: https://email-sdk.dev/docs/guides/authoring/publish-community-adapter.md Illustrates the typical file structure for a community email adapter package. ```txt email-sdk-acme-mail/ src/ index.ts acme-mail.ts plugin.ts acme-mail.test.ts package.json tsconfig.json README.md ``` -------------------------------- ### Example Plugin Usage in Client Source: https://email-sdk.dev/docs/guides/authoring/publish-community-plugin.md How to use the plugin within the `createEmailClient` configuration. ```typescript createEmailClient({ plugins: [auditLogPlugin()], }); ``` -------------------------------- ### Create Email Client with Plugins Source: https://email-sdk.dev/docs/plugins.md Example of creating an email client and configuring it with built-in plugins for defaults and observability, along with a custom adapter. ```typescript import { createEmailClient } from "@opencoredev/email-sdk"; import { defaultsPlugin } from "@opencoredev/email-sdk/plugins/defaults"; import { observabilityPlugin } from "@opencoredev/email-sdk/plugins/observability"; import { resend } from "@opencoredev/email-sdk/resend"; export const email = createEmailClient({ adapters: [resend({ apiKey: process.env.RESEND_API_KEY! })], plugins: [ defaultsPlugin({ headers: { "X-App": "acme" }, replyTo: "support@acme.com" }), observabilityPlugin({ log: (event) => console.log(event.type, event.provider) }), ], }); ``` -------------------------------- ### Plugin Package Structure Source: https://email-sdk.dev/docs/guides/authoring/publish-community-plugin.md Example directory structure for an email SDK plugin package. ```txt email-sdk-audit-log/ src/ index.ts audit-log.ts audit-log.test.ts package.json README.md ``` -------------------------------- ### Email SDK Hooks Example Source: https://email-sdk.dev/docs/concepts/hooks.md Demonstrates how to configure and use various hooks (beforeSend, afterSend, onRetry, onError) when creating an email client. This example uses the Resend adapter and logs events to the console. ```typescript import { createEmailClient } from "@opencoredev/email-sdk"; import { resend } from "@opencoredev/email-sdk/resend"; const email = createEmailClient({ adapters: [resend({ apiKey: process.env.RESEND_API_KEY! })], retry: { retries: 2 }, hooks: { beforeSend({ provider, attempt, metadata }) { console.log("email.attempt", { provider, attempt, route: metadata?.route }); }, afterSend({ provider, attempt, response }) { console.log("email.sent", { provider, attempt, id: response.id }); }, onRetry({ provider, nextAttempt, delayMs, error }) { console.warn("email.retry", { provider, nextAttempt, delayMs, error }); }, onError({ provider, attempt, error }) { console.error("email.failed", { provider, attempt, error }); }, }, }); await email.send(message, { metadata: { route: "checkout.receipt" } }); ``` -------------------------------- ### Install Email SDK Skill Source: https://email-sdk.dev/docs/agents/skill.md Install the email-sdk skill using the skills CLI. This skill helps coding agents integrate the Email SDK properly. ```bash npx skills add opencoredev/email-sdk --skill email-sdk ``` -------------------------------- ### Display CLI Version Source: https://email-sdk.dev/docs/reference/cli.md Reads the metadata of the installed package. Use this to check the installed version against documentation. ```bash npx email-sdk version # @opencoredev/email-sdk 0.6.1 ``` ```bash npx email-sdk version --json # { "name": "@opencoredev/email-sdk", "version": "0.6.1" } ``` -------------------------------- ### Run Email SDK CLI (No Install with Bun) Source: https://email-sdk.dev/docs/getting-started/install.md Execute the email-sdk CLI without installing it by pointing bunx at the scoped package. This is useful for one-off checks. ```bash bunx --bun --package @opencoredev/email-sdk email-sdk adapters ``` -------------------------------- ### Community Registry Entry Example Source: https://email-sdk.dev/docs/guides/authoring/publish-community-plugin.md Example JSON entry for a plugin in the community registry. ```json { "name": "Audit log", "package": "email-sdk-audit-log", "kind": "plugin", "status": "community", "description": "Records every send outcome on a typed client extension.", "href": "https://www.npmjs.com/package/email-sdk-audit-log", "repo": "https://github.com/acme/email-sdk-audit-log", "maintainer": "acme", "pluginId": "audit-log" } ``` -------------------------------- ### Sending Email with Resend and SMTP Fallback Source: https://email-sdk.dev/docs/adapters/field-support.md Demonstrates configuring an email client with Resend as the primary adapter and SMTP as a fallback. This setup ensures that if Resend cannot handle certain fields (like headers in this example), the message can still be sent via SMTP. ```typescript const email = createEmailClient({ adapters: [resend({ apiKey: process.env.RESEND_API_API_KEY! }), smtp({ host: process.env.SMTP_HOST! })], fallback: ["smtp"], }); await email.send({ from: "Acme ", to: "user@example.com", replyTo: "support@example.com", subject: "Password reset", text: "Use this link to reset your password.", headers: { "X-Template": "password-reset" }, }); ``` -------------------------------- ### Initialize Email Client with Multiple Adapters Source: https://email-sdk.dev/docs/adapters.md Configure the Email SDK client with multiple adapters, such as Resend and SMTP, and define a fallback strategy. This setup allows routing emails through specific adapters or using a fallback in case of failure. ```typescript import { createEmailClient } from "@opencoredev/email-sdk"; import { resend } from "@opencoredev/email-sdk/resend"; import { smtp } from "@opencoredev/email-sdk/smtp"; const email = createEmailClient({ adapters: [ resend({ apiKey: process.env.RESEND_API_KEY! }), smtp({ host: process.env.SMTP_HOST!, auth: { user: process.env.SMTP_USER!, pass: process.env.SMTP_PASS! }, }), ], fallback: ["smtp"], }); // route one send through a specific adapter await email.send(message, { adapter: "smtp" }); ``` -------------------------------- ### Verify Email Sending with CLI Source: https://email-sdk.dev/docs/getting-started/quickstart.md Use the CLI to verify environment setup and perform a dry run of sending an email. Replace 're_...' with your actual API key. ```bash RESEND_API_KEY="re_..." npx email-sdk doctor --adapter resend ``` ```bash npx email-sdk send \ --adapter resend \ --from "Acme " \ --to "user@example.com" \ --subject "Hello" \ --text "It works" \ --dry-run ``` -------------------------------- ### Missing Environment Variable Error Source: https://email-sdk.dev/docs/reference/cli.md Example error message when a required environment variable for an adapter is not set. ```txt Missing environment for resend: RESEND_API_KEY ``` -------------------------------- ### Create Email Client with Multiple Adapters Source: https://email-sdk.dev/docs/concepts/adapter-model.md Initialize the email client by providing an array of configured adapters. The client uses these adapters for sending emails. Ensure API keys or tokens are securely managed, for example, using environment variables. ```typescript import { createEmailClient } from "@opencoredev/email-sdk"; import { resend } from "@opencoredev/email-sdk/resend"; import { postmark } from "@opencoredev/email-sdk/postmark"; const email = createEmailClient({ adapters: [ resend({ apiKey: process.env.RESEND_API_KEY! }), postmark({ serverToken: process.env.POSTMARK_SERVER_TOKEN! }), ], // defaultAdapter is optional — it falls back to the first adapter ("resend" here) }); ``` -------------------------------- ### Import Email SDK Client and Adapters Source: https://email-sdk.dev/docs/getting-started/install.md Import the main email client and specific adapters from the installed package. Ensure you are using Node.js 20+ or Bun 1.1+. ```typescript import { createEmailClient } from "@opencoredev/email-sdk"; import { resend } from "@opencoredev/email-sdk/resend"; ``` -------------------------------- ### Configure Brevo Email Client Source: https://email-sdk.dev/docs/adapters/brevo.md Set up the Brevo email client using your API key. Ensure the API key is stored securely, for example, in environment variables. ```typescript import { createEmailClient } from "@opencoredev/email-sdk"; import { brevo } from "@opencoredev/email-sdk/brevo"; export const email = createEmailClient({ adapters: [brevo({ apiKey: process.env.BREVO_API_KEY! })], }); ``` -------------------------------- ### Community Adapter Registry Entry Source: https://email-sdk.dev/docs/guides/authoring/publish-community-adapter.md Example JSON object for adding a new adapter to the community registry. Ensure all required fields are present and unique. ```json { "name": "Acme Mail", "package": "email-sdk-acme-mail", "kind": "adapter", "status": "community", "description": "Adds an Acme Mail provider adapter for Email SDK.", "href": "https://www.npmjs.com/package/email-sdk-acme-mail", "repo": "https://github.com/acme/email-sdk-acme-mail", "maintainer": "acme", "pluginId": "acme-mail", "adapter": "acme-mail", "importName": "acmeMailPlugin" } ``` -------------------------------- ### AcmeMail Adapter Implementation Source: https://email-sdk.dev/docs/reference/adapter-contract.md An example implementation of the EmailProvider interface for the AcmeMail service. It demonstrates how to send an email, handle HTTP responses, and throw custom errors. ```typescript import { EmailProviderError } from "@opencoredev/email-sdk"; import type { EmailProvider } from "@opencoredev/email-sdk"; export const acmeMail: EmailProvider = { name: "acme-mail", async send(message, context) { const response = await fetch("https://api.acme-mail.example/send", { method: "POST", signal: context.signal, headers: { "Content-Type": "application/json" }, body: JSON.stringify(toAcmePayload(message)), }); if (!response.ok) { throw new EmailProviderError(`acme-mail failed with HTTP ${response.status}.`, { provider: "acme-mail", status: response.status, retryable: response.status === 429 || response.status >= 500, }); } const body = await response.json(); return { provider: "acme-mail", id: body.id, raw: body }; }, }; ``` -------------------------------- ### Configure Sequenzy Email Client Source: https://email-sdk.dev/docs/adapters/sequenzy.md Set up the email client with the Sequenzy adapter, providing your API key. Ensure the API key is securely stored, for example, in environment variables. ```typescript import { createEmailClient, } from "@opencoredev/email-sdk"; import { sequenzy, } from "@opencoredev/email-sdk/sequenzy"; export const email = createEmailClient({ adapters: [sequenzy({ apiKey: process.env.SEQUENZY_API_KEY! })], }); ``` -------------------------------- ### Create Email Client with Adapters Source: https://email-sdk.dev/docs/reference/client.md Instantiate the email client with multiple adapters (Resend and SMTP), specifying a default adapter, fallback options, and retry configuration. Ensure API keys and host details are securely managed, for example, via environment variables. ```typescript import { createEmailClient } from "@opencoredev/email-sdk"; import { resend } from "@opencoredev/email-sdk/resend"; import { smtp } from "@opencoredev/email-sdk/smtp"; const email = createEmailClient({ adapters: [resend({ apiKey: process.env.RESEND_API_KEY! }), smtp({ host: process.env.SMTP_HOST! })], defaultAdapter: "resend", fallback: ["smtp"], retry: { retries: 2 }, }); ``` -------------------------------- ### Verify Sequenzy Adapter Configuration via CLI Source: https://email-sdk.dev/docs/adapters/sequenzy.md Use the email-sdk doctor command to verify your Sequenzy API key and sender verification setup. Replace 'seq_live_...' with your actual API key. ```bash SEQUENZY_API_KEY="seq_live_..." npx email-sdk doctor --adapter sequenzy ``` -------------------------------- ### Configure Multiple Adapters with Fallbacks Source: https://email-sdk.dev/docs/authentication.md Configure multiple email adapters, such as Resend and SES, to route emails and provide fallbacks. Ensure that fallback adapters support the same fields. This example also includes retry configuration. ```typescript import { createEmailClient } from "@opencoredev/email-sdk"; import { resend } from "@opencoredev/email-sdk/resend"; import { ses } from "@opencoredev/email-sdk/ses"; export const email = createEmailClient({ adapters: [ resend({ apiKey: process.env.RESEND_API_KEY! }), ses({ accessKeyId: process.env.AWS_ACCESS_KEY_ID!, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!, region: process.env.AWS_REGION!, }), ], retry: { retries: 1 }, }); ``` -------------------------------- ### Display CLI Help Source: https://email-sdk.dev/docs/reference/cli.md Prints usage information, all send flags, and adapter-specific option groups. Running the CLI with no command also displays help. ```bash npx email-sdk help ``` -------------------------------- ### Audit Plugin Example Source: https://email-sdk.dev/docs/plugins/writing-plugins.md An example plugin that logs the provider and response ID after a send operation. This demonstrates the use of the 'afterSend' middleware. ```typescript import type { EmailPlugin } from "@opencoredev/email-sdk"; export function auditPlugin(): EmailPlugin { return { id: "audit", middleware: [ { afterSend(event) { console.log("sent", event.provider, event.response.id); }, }, ], }; } ``` -------------------------------- ### Cancel a Queued Email Source: https://email-sdk.dev/docs/components/convex-email.md Cancels an email that has not yet started processing. Returns true if the email was still queued, and false if it had already started processing, was sent, failed, or was already canceled. ```typescript const canceled = await email.cancel(ctx, { emailId }); // true if it was still queued; false once processing, sent, failed, or canceled ``` -------------------------------- ### Create Email Client with Plugin Source: https://email-sdk.dev/docs/guides/authoring/create-adapter.md Initializes an email client using a custom plugin. ```typescript import { createEmailClient } from "@opencoredev/email-sdk"; import { acmeMailPlugin } from "email-sdk-acme-mail"; const email = createEmailClient({ plugins: [acmeMailPlugin({ apiKey: process.env.ACME_MAIL_API_KEY! })], }); ``` -------------------------------- ### Running tests with Bun Source: https://email-sdk.dev/docs/guides/test-email-behavior.md Execute your test suite using the `bun test` command. Ensure that only test-specific adapters like `memoryProvider` or `failingProvider` are registered to avoid unintended network calls. ```bash bun test ``` -------------------------------- ### Verify Brevo Adapter Configuration via CLI Source: https://email-sdk.dev/docs/adapters/brevo.md Use the CLI to verify your Brevo API key and sender configuration. This command checks if the adapter is set up correctly without sending an actual email. ```bash BREVO_API_KEY="xkeysib-..." npx email-sdk doctor --adapter brevo ``` -------------------------------- ### Configure Primitive Email Client Source: https://email-sdk.dev/docs/adapters/primitive.md Set up the email client with the Primitive adapter. Ensure your Primitive API key is available as an environment variable. ```typescript import { createEmailClient } from "@opencoredev/email-sdk"; import { primitive } from "@opencoredev/email-sdk/primitive"; export const email = createEmailClient({ adapters: [primitive({ apiKey: process.env.PRIMITIVE_API_KEY! })], }); ``` -------------------------------- ### Successful Send Response Source: https://email-sdk.dev/docs/reference/cli.md Example of a successful response from the email sending CLI when using the Resend adapter. ```json { "provider": "resend", "id": "0f8d2a3e-...", "messageId": "0f8d2a3e-...", "raw": { "id": "0f8d2a3e-..." } } ``` -------------------------------- ### Email SDK Capture Plugin Usage Source: https://email-sdk.dev/docs/plugins/built-in/capture.md Demonstrates how to initialize the Email SDK with the capture plugin and memory adapter, send an email, and assert captured events. ```typescript import { createEmailClient, } from "@opencoredev/email-sdk"; import { capturePlugin } from "@opencoredev/email-sdk/plugins/capture"; import { memoryProvider } from "@opencoredev/email-sdk/testing"; const email = createEmailClient({ adapters: [memoryProvider()], plugins: [capturePlugin()], }); await email.send({ from: "Acme ", to: "user@example.com", subject: "Welcome", text: "Your account is ready.", }); const sent = email.capture.events.find((event) => event.type === "afterSend"); expect(sent?.provider).toBe("memory"); expect(email.capture.events.map((event) => event.type)).toEqual(["beforeSend", "afterSend"]); ``` -------------------------------- ### Export Email Adapter as a Plugin Source: https://email-sdk.dev/docs/guides/authoring/create-adapter.md Creates a plugin wrapper for an email adapter, allowing easy installation in email clients. ```typescript import type { EmailPlugin } from "@opencoredev/email-sdk"; import { acmeMail, type AcmeMailOptions } from "./acme-mail"; export function acmeMailPlugin(options: AcmeMailOptions): EmailPlugin { return { id: "acme-mail", adapters: [acmeMail(options)], }; } ``` -------------------------------- ### Verify MailerSend Configuration via CLI Source: https://email-sdk.dev/docs/adapters/mailersend.md Use the email-sdk CLI to verify your MailerSend API key and domain setup. ```bash MAILERSEND_API_KEY="mlsn..." npx email-sdk doctor --adapter mailersend ``` -------------------------------- ### Dry Run Send Plan Output Source: https://email-sdk.dev/docs/reference/cli.md Example output of a successful dry run, showing the validated message plan before sending. ```json { "ok": true, "adapter": "resend", "message": { "from": "Acme ", "to": ["user@example.com"], "subject": "Hello", "text": "It works" } } ``` -------------------------------- ### Create Email Client and Send Email with Resend Adapter Source: https://email-sdk.dev/docs/index.md This snippet demonstrates how to initialize the Email SDK with the Resend adapter and send a basic transactional email. Ensure the RESEND_API_KEY environment variable is set. ```typescript import { createEmailClient } from "@opencoredev/email-sdk"; import { resend } from "@opencoredev/email-sdk/resend"; const email = createEmailClient({ adapters: [resend({ apiKey: process.env.RESEND_API_KEY! })], }); await email.send({ from: "Acme ", to: "user@example.com", subject: "Welcome", text: "Your account is ready.", }); ``` -------------------------------- ### Inferring EmailClient Type with Plugins Source: https://email-sdk.dev/docs/plugins/api.md Demonstrates how `createEmailClient` infers the `EmailClient` type based on the provided plugins, specifically showing an example with a `capturePlugin`. ```typescript // EmailClient<{ capture: EmailCaptureStore }> const email = createEmailClient({ adapters: [memoryProvider()], plugins: [capturePlugin()], }); ``` -------------------------------- ### Verify Primitive Adapter via CLI Source: https://email-sdk.dev/docs/adapters/primitive.md Use the email-sdk CLI to verify your Primitive adapter configuration. This command checks if the API key and sender domain are correctly set up. ```bash PRIMITIVE_API_KEY="prim_..." npx email-sdk doctor --adapter primitive ``` -------------------------------- ### Register Acme Mail Adapter Source: https://email-sdk.dev/docs/plugins/writing-plugins.md Defines a plugin to register the Acme Mail adapter. Use this for one-call setup of community adapter packages. ```typescript import type { EmailPlugin } from "@opencoredev/email-sdk"; export function acmeMail(options: { apiKey: string }): EmailPlugin { return { id: "acme-mail", adapters: [createAcmeAdapter(options)], // an EmailProvider }; } ``` -------------------------------- ### Configure JetEmail Client Source: https://email-sdk.dev/docs/adapters/jetemail.md Set up the email client with the JetEmail adapter. Ensure your JetEmail transactional API key is available as an environment variable. ```typescript import { createEmailClient } from "@opencoredev/email-sdk"; import { jetemail } from "@opencoredev/email-sdk/jetemail"; export const email = createEmailClient({ adapters: [jetemail({ apiKey: process.env.JETEMAIL_API_KEY! })], }); ``` -------------------------------- ### Configure SparkPost Email Client Source: https://email-sdk.dev/docs/adapters/sparkpost.md Set up the email client with the SparkPost adapter, providing your API key. Ensure the API key has Transmissions permission. ```typescript import { createEmailClient } from "@opencoredev/email-sdk"; import { sparkpost } from "@opencoredev/email-sdk/sparkpost"; export const email = createEmailClient({ adapters: [sparkpost({ apiKey: process.env.SPARKPOST_API_KEY! })], }); ``` -------------------------------- ### Configure Lettermint Adapter Source: https://email-sdk.dev/docs/adapters/lettermint.md Initialize the email client with the Lettermint adapter, providing the API token. ```typescript import { createEmailClient, } from "@opencoredev/email-sdk"; import { lettermint, } from "@opencoredev/email-sdk/lettermint"; export const email = createEmailClient({ adapters: [lettermint({ apiToken: process.env.LETTERMINT_API_TOKEN! })], }); ``` -------------------------------- ### Convex Email Test Helpers Setup Source: https://email-sdk.dev/docs/components/convex-email.md Set up test helpers for Convex Email using convex-test. This includes registering the component and configuring test settings. ```typescript import { convexTest } from "convex-test"; import { memoryAdapter, registerConvexEmail, testEmailConfig } from "@opencoredev/convex-email/test"; import schema from "./schema"; const t = convexTest(schema, import.meta.glob("./**/*.ts")); registerConvexEmail(t); // mounts the component as "convexEmail" ``` -------------------------------- ### Get Registered Email Adapter Source: https://email-sdk.dev/docs/reference/client.md Retrieves a registered email adapter by name. Throws `EmailProviderNotFoundError` if the adapter is not found. Useful for accessing adapter-specific escape hatches. ```typescript adapter(name: string): TProvider ``` -------------------------------- ### Verify SparkPost Adapter via CLI Source: https://email-sdk.dev/docs/adapters/sparkpost.md Use the email-sdk CLI to verify the SparkPost adapter configuration and connectivity. ```bash SPARKPOST_API_KEY="..." npx email-sdk doctor --adapter sparkpost ``` -------------------------------- ### Configure Email Client with Observability Source: https://email-sdk.dev/docs/guides/production-send-pipeline.md Set up the email client with multiple adapters, fallback routes, retry logic, and observability plugins. The observability plugin logs and emits metrics for email events. ```typescript import { createEmailClient } from "@opencoredev/email-sdk"; import { defaultsPlugin } from "@opencoredev/email-sdk/plugins/defaults"; import { observabilityPlugin } from "@opencoredev/email-sdk/plugins/observability"; import { postmark } from "@opencoredev/email-sdk/postmark"; import { resend } from "@opencoredev/email-sdk/resend"; export const email = createEmailClient({ adapters: [ resend({ apiKey: process.env.RESEND_API_KEY! }), postmark({ serverToken: process.env.POSTMARK_SERVER_TOKEN! }), ], fallback: ["postmark"], retry: { retries: 2 }, plugins: [ defaultsPlugin({ replyTo: "Acme Support ", headers: { "X-Service": "checkout" }, sendMetadata: { service: "checkout" }, }), observabilityPlugin({ log(event) { console.log(event.type, event.provider, event.attempt, event.metadata); }, metric(event) { // increment counters: emails_sent_total{provider}, emails_error_total{provider}, ... }, }), ], }); ``` -------------------------------- ### Configure MailPace Email Client Source: https://email-sdk.dev/docs/adapters/mailpace.md Set up the email client with the MailPace adapter. Ensure the MAILPACE_API_KEY environment variable is set. ```typescript import { createEmailClient } from "@opencoredev/email-sdk"; import { mailpace } from "@opencoredev/email-sdk/mailpace"; export const email = createEmailClient({ adapters: [mailpace({ apiKey: process.env.MAILPACE_API_KEY! })], }); ``` -------------------------------- ### Configure ZeptoMail Client Source: https://email-sdk.dev/docs/adapters/zeptomail.md Initialize the email client with the ZeptoMail adapter. Ensure your ZeptoMail send mail token is available as an environment variable. ```typescript import { createEmailClient } from "@opencoredev/email-sdk"; import { zeptomail } from "@opencoredev/email-sdk/zeptomail"; export const email = createEmailClient({ adapters: [zeptomail({ token: process.env.ZEPTOMAIL_TOKEN! })], }); ``` -------------------------------- ### Initialize Email Client with Observability Plugin Source: https://email-sdk.dev/docs/plugins/built-in/observability.md Configure the email client with the observability plugin to enable structured event logging and metrics. Ensure necessary API keys and logger/metrics instances are available. ```typescript import { createEmailClient } from "@opencoredev/email-sdk"; import { observabilityPlugin } from "@opencoredev/email-sdk/plugins/observability"; import { resend } from "@opencoredev/email-sdk/resend"; export const email = createEmailClient({ adapters: [resend({ apiKey: process.env.RESEND_API_KEY! })], plugins: [ observabilityPlugin({ log(event) { // any structured logger works the same way (pino, winston, console) logger.info({ ...event }, event.type); }, metric(event) { metrics.increment(`email.${event.type}`, { provider: event.provider }); }, }), ], }); ``` -------------------------------- ### Verify Resend Adapter via CLI Source: https://email-sdk.dev/docs/adapters/resend.md Use the CLI to verify the Resend adapter configuration and connectivity. The RESEND_API_KEY environment variable must be set. ```bash RESEND_API_KEY="re_..." npx email-sdk doctor --adapter resend ``` -------------------------------- ### Send Email from JSON File with Overrides Source: https://email-sdk.dev/docs/reference/cli.md Sends an email using a JSON file for message content, with specific flags overriding file values. This example performs a dry run. ```json { "from": "Acme ", "to": ["user@example.com"], "subject": "Welcome", "html": "

Your account is ready.

", "tags": [{ "name": "type", "value": "welcome" }] } ``` ```bash npx email-sdk send --adapter resend --message ./message.json --to "qa@example.com" --dry-run ``` -------------------------------- ### Configure Cloudflare Email Client Source: https://email-sdk.dev/docs/adapters/cloudflare.md Set up the email client with the Cloudflare adapter, providing API token and account ID. Ensure these are securely stored and accessed, for example, via environment variables. ```typescript import { createEmailClient } from "@opencoredev/email-sdk"; import { cloudflare } from "@opencoredev/email-sdk/cloudflare"; export const email = createEmailClient({ adapters: [ cloudflare({ apiToken: process.env.CLOUDFLARE_API_TOKEN!, accountId: process.env.CLOUDFLARE_ACCOUNT_ID!, }), ], }); ``` -------------------------------- ### Create Email Client with Fallback SMTP Adapter Source: https://email-sdk.dev/docs/getting-started/quickstart.md Configure the email client with Resend as the primary adapter and SMTP as a fallback. Ensure SMTP credentials and host are set in environment variables. ```typescript import { createEmailClient } from "@opencoredev/email-sdk"; import { resend } from "@opencoredev/email-sdk/resend"; import { smtp } from "@opencoredev/email-sdk/smtp"; export const email = createEmailClient({ adapters: [ resend({ apiKey: process.env.RESEND_API_KEY! }), smtp({ host: process.env.SMTP_HOST!, port: 587, auth: { user: process.env.SMTP_USER!, pass: process.env.SMTP_PASS! }, }), ], fallback: ["smtp"], }); ``` -------------------------------- ### Send Email with Custom Options Source: https://email-sdk.dev/docs/reference/client.md Example of sending an email using `email.send` with specific routing, fallback adapters, retry count, and metadata. This demonstrates overriding client-level configurations for a single send operation. ```typescript const result = await email.send(message, { adapter: "resend", fallbackAdapters: ["smtp"], retries: 2, idempotencyKey: "receipt:order_123", metadata: { route: "checkout.receipt" }, }); ``` -------------------------------- ### Configure Scaleway Email Client Source: https://email-sdk.dev/docs/adapters/scaleway.md Set up the email client with the Scaleway adapter, providing your secret key and project ID. Ensure these are available as environment variables. ```typescript import { createEmailClient } from "@opencoredev/email-sdk"; import { scaleway } from "@opencoredev/email-sdk/scaleway"; export const email = createEmailClient({ adapters: [ scaleway({ secretKey: process.env.SCALEWAY_SECRET_KEY!, projectId: process.env.SCALEWAY_PROJECT_ID!, }), ], }); ``` -------------------------------- ### createEmailClient(options) Source: https://email-sdk.dev/docs/reference/client.md Initializes the email client with provided options. This function allows configuration of adapters, default adapter, fallback mechanisms, retry strategies, hooks, and plugins. ```APIDOC ## `createEmailClient(options)` ### Description Initializes the email client with provided options. This function allows configuration of adapters, default adapter, fallback mechanisms, retry strategies, hooks, and plugins. ### Method `createEmailClient(options)` ### Parameters #### Options Object - **adapters** (EmailProvider[]) - Optional - Adapters to register, keyed by their routing names. Defaults to `[]`. - **defaultAdapter** (string) - Optional - Routing name used when a send sets no adapter. Defaults to the first registered adapter. - **fallback** (string[]) - Optional - Routing names tried in order after the selected adapter finally fails. Defaults to `[]`. - **retry** (EmailRetryConfig) - Optional - Per-adapter retry budget, backoff delay, and retry predicate. Defaults to no retries. - **hooks** (EmailHooks) - Optional - Observe-only callbacks: beforeSend, afterSend, onError, onRetry. - **plugins** (EmailPlugin[]) - Optional - Plugins that add adapters, hooks, middleware, or client extensions. Defaults to `[]`. ### Request Example ```ts import { createEmailClient } from "@opencoredev/email-sdk"; import { resend } from "@opencoredev/email-sdk/resend"; import { smtp } from "@opencoredev/email-sdk/smtp"; const email = createEmailClient({ adapters: [resend({ apiKey: process.env.RESEND_API_KEY! }), smtp({ host: process.env.SMTP_HOST! })], defaultAdapter: "resend", fallback: ["smtp"], retry: { retries: 2 }, }); ``` ### Error Handling Construction fails fast with an `EmailValidationError` for a duplicate adapter routing name (`Duplicate email adapter "x".`) or plugin id (`Duplicate email plugin "x".`), and for an empty client (`createEmailClient requires a default adapter.`). A `defaultAdapter` that is not registered throws `EmailProviderNotFoundError`. ``` -------------------------------- ### Email Attachment with URL Source: https://email-sdk.dev/docs/components/convex-email.md Example of attaching a file to an email using a public URL. The worker will fetch the content from the provided URL at send time. Ensure the URL is publicly accessible via HTTPS. ```typescript attachments: [ { filename: "invoice.pdf", url: "https://files.acme.com/invoices/inv_123.pdf" }, ] ``` -------------------------------- ### Register Convex Email Component Source: https://email-sdk.dev/docs/components/convex-email.md Configure the Convex app to use the convex-email component by defining environment variables and passing them through. This setup ensures the component can access necessary credentials like API keys. ```typescript import { defineApp } from "convex/server"; import { v } from "convex/values"; import convexEmail from "@opencoredev/convex-email/convex.config.js"; const app = defineApp({ env: { RESEND_API_KEY: v.optional(v.string()), SMTP_HOST: v.optional(v.string()), SMTP_PORT: v.optional(v.string()), SMTP_USER: v.optional(v.string()), SMTP_PASS: v.optional(v.string()), }, }); app.use(convexEmail, { env: { RESEND_API_KEY: app.env.RESEND_API_KEY, SMTP_HOST: app.env.SMTP_HOST, SMTP_PORT: app.env.SMTP_PORT, SMTP_USER: app.env.SMTP_USER, SMTP_PASS: app.env.SMTP_PASS, }, }); export default app; ``` -------------------------------- ### Custom Client Keys for Capture Plugin Source: https://email-sdk.dev/docs/plugins/built-in/capture.md Shows how to use distinct client keys to mount multiple instances of the capture plugin on the same client. ```typescript const email = createEmailClient({ adapters: [memoryProvider()], plugins: [ capturePlugin({ id: "capture:primary", clientKey: "primaryCapture" }), capturePlugin({ id: "capture:audit", clientKey: "auditCapture" }), ], }); email.primaryCapture.events; // typed EmailCaptureStore email.auditCapture.clear(); ``` -------------------------------- ### Send Email with Sequenzy Source: https://email-sdk.dev/docs/adapters/sequenzy.md Send an email using the Sequenzy adapter. This example demonstrates sending to a single recipient with HTML content and custom metadata. The result contains the Sequenzy jobId and a list of accepted recipients. ```typescript const result = await email.send({ from: "Acme ", to: [{ email: "user@example.com", name: "Ada" }], replyTo: "support@acme.com", subject: "You've been invited to Acme", html: "

Ada invited you to the Acme workspace.

", metadata: { inviterName: "Ada", workspaceName: "Acme" }, }); console.log(result.id); // Sequenzy jobId; result.accepted lists the recipients Sequenzy took ``` -------------------------------- ### Verify Scaleway Adapter Configuration via CLI Source: https://email-sdk.dev/docs/adapters/scaleway.md Use the email-sdk CLI to verify your Scaleway adapter configuration by providing necessary environment variables. ```bash SCALEWAY_SECRET_KEY="..." SCALEWAY_PROJECT_ID="..." npx email-sdk doctor --adapter scaleway ``` -------------------------------- ### Send Test Email from CLI with Mailgun Source: https://email-sdk.dev/docs/adapters/mailgun.md Perform a test send using the Mailgun adapter via the email-sdk CLI. The --dry-run flag simulates a send without actually delivering an email, useful for initial setup verification. ```bash MAILGUN_API_KEY="key-..." npx email-sdk send \ --adapter mailgun \ --domain mg.acme.com \ --from "Acme " \ --to user@example.com \ --subject "Mailgun smoke test" \ --text "It works" \ --dry-run ``` -------------------------------- ### Configure Unosend Adapter Source: https://email-sdk.dev/docs/adapters/unosend.md This snippet shows how to create an email client using the Unosend adapter. It requires your Unosend API key, which should be stored securely (e.g., in environment variables). ```APIDOC ## Configure Unosend Adapter This section details how to set up the Unosend adapter for sending emails. ### Description To use the Unosend adapter, you need to create a server-side API key from your Unosend account and verify the domain from which you will send emails. The adapter then uses this API key to authenticate requests to the Unosend REST API. ### Configuration Options - **apiKey** (string, required): Your Unosend API key. This is essential for authenticating with the Unosend service. - **baseUrl** (string, optional): Allows you to override the default API origin. This is useful for scenarios like using a proxy server. - **fetch** (typeof fetch, optional): You can provide a custom fetch implementation, which is helpful for testing or for specific runtime environments. ### Example Usage ```ts import { createEmailClient } from "@opencoredev/email-sdk"; import { unosend } from "@opencoredev/email-sdk/unosend"; export const email = createEmailClient({ adapters: [unosend({ apiKey: process.env.UNOSEND_API_KEY! })], }); ``` ``` -------------------------------- ### Mounting Multiple Defaults Plugins Source: https://email-sdk.dev/docs/plugins/built-in/defaults.md Demonstrates how to mount multiple instances of the defaults plugin with distinct IDs and custom headers or tags. Later layers will see the merged results of earlier ones. ```typescript plugins: [ defaultsPlugin({ id: "defaults:org", headers: { "X-Org": "acme" } }), defaultsPlugin({ id: "defaults:billing", tags: [{ name: "team", value: "billing" }] }), ]; ``` -------------------------------- ### Verify Email Adapters from CLI Source: https://email-sdk.dev/docs/guides/production-send-pipeline.md Use the email-sdk CLI to check the status and configuration of specific email adapters. This is useful for diagnosing environment issues before sending emails. ```bash npx email-sdk doctor --adapter resend npx email-sdk doctor --adapter postmark ```