@absolutejs/dispatch-postmark
v0.0.2
Published
Postmark-backed EmailAdapter for @absolutejs/dispatch. Maps EmailMessage to Postmark's sendEmail params; surfaces the MessageID as DispatchResult.id.
Maintainers
Readme
@absolutejs/dispatch-postmark
Postmark-backed EmailAdapter for
@absolutejs/dispatch.
Docs: absolutejs.com/documentation/dispatch-overview#postmark
Install
bun add @absolutejs/dispatch @absolutejs/dispatch-postmark postmarkUsage
import { ServerClient } from 'postmark';
import { createDispatcher } from '@absolutejs/dispatch';
import { createPostmarkAdapter } from '@absolutejs/dispatch-postmark';
const postmark = new ServerClient(process.env.POSTMARK_SERVER_TOKEN!);
const dispatcher = createDispatcher({
email: createPostmarkAdapter({
client: postmark,
defaultFrom: '[email protected]',
// Optional — defaults to Postmark's transactional stream.
// messageStream: 'broadcast',
}),
});
await dispatcher.email({
to: '[email protected]',
subject: 'Welcome to Acme',
text: 'Click here to verify: ...',
// metadata.tag → Postmark Tag (single-string analytics segment);
// other string entries → Postmark Metadata (string→string map):
metadata: { tag: 'onboarding', campaign: 'welcome-v2' },
});API
createPostmarkAdapter({
client, // Required — your `new ServerClient(serverToken)`
defaultFrom?, // Required if your messages don't set `from`
messageStream?, // Default: Postmark's transactional stream
mapMetadata?, // Customize EmailMessage.metadata → Postmark Tag/Metadata
})mapMetadata
By default the adapter:
- Extracts
metadata.tag(string) into Postmark'sTagfield (a single-string analytics segment per message) - Maps every OTHER string-valued entry into Postmark's
Metadata(a string→string map) - Filters out non-string values (Postmark Metadata values must be strings)
Override to customize:
createPostmarkAdapter({
client: postmark,
mapMetadata: (metadata) => ({
Tag: typeof metadata.flow === 'string' ? metadata.flow : 'transactional',
Metadata: { tenant: String(metadata.tenant ?? 'unknown') },
}),
});Error mapping
Postmark's response shape:
{ MessageID, SubmittedAt, To, ErrorCode, Message }ErrorCode !== 0(and not undefined) → adapter throws withPostmark ErrorCode <n>: <Message>.@absolutejs/dispatch's error path records the exception on thedispatch.email.sendspan, bumps the failed counter, and emitsdispatch.email.failed.ErrorCode === 0(or undefined) → treated as success.DispatchResult.id=response.MessageID.
License
Apache 2.0. Tier B substrate-adjacent — rides
@absolutejs/dispatch (BSL Tier A) and postmark (MIT).
