Email SDK
GuidesExtend

Create your first plugin

Add typed middleware and a client extension without changing adapter behavior.

This plugin records successful receipt ids and exposes them through email.receipts.

Define the extension

src/receipt-plugin.ts
import type { EmailPlugin } from "@opencoredev/email-sdk";

export function receiptPlugin(): EmailPlugin<{
  receipts: readonly { adapter: string; id?: string }[];
}> {
  const receipts: { adapter: string; id?: string }[] = [];

  return {
    id: "receipts",
    middleware: [
      {
        afterSend(event) {
          receipts.push({
            adapter: event.response.adapter,
            id: event.response.id,
          });
        },
      },
    ],
    extendClient() {
      return { receipts };
    },
  };
}

Mount the plugin

src/email.ts
const email = createEmailClient({
  adapters: [adapter],
  plugins: [receiptPlugin()],
});

await email.send(message);
console.log(email.receipts);

extendClient must not reuse adapters, defaultAdapter, validate, send, sendMany, sendPersonalized, adapter, withAdapter, or another extension key.

Choose hooks or middleware

Use hooks for best-effort observation because hook exceptions are swallowed. Use middleware when failure should be visible as EmailMiddlewareError or when you need to replace the message or send options before validation.

Keep setup synchronous

Plugin adapter registration and extendClient run during synchronous client construction. Do asynchronous credential or remote configuration work before calling createEmailClient.

Plugin API

See exact plugin, hook, middleware, and extension types.

Publish a plugin

Package and document the extension for external users.

On this page