Email, SMS, Slack — @spfn/notification gives each channel the
same call shape: recipient, template, data in; a SendResult back, never a
throw. Providers plug in, templates render with filters, and pg-boss carries the
scheduled and the bulk.
Notifications are the same job in every app: render a message, hand
it to a vendor, remember what happened. This package ships that job as one surface — a
template system with variable substitution and filters, delivery through pluggable
providers, scheduling and distributed bulk sending on pg-boss, and an optional history
table with engagement tracking on top. It configures from environment variables by
default, with configureNotification for code-level overrides, and every
send resolves to a SendResult you check instead of an exception you catch.
A provider is a name and a send() function — nothing
more. AWS SES and SNS come built in, but as optional dependencies: their SDKs install
only if you use them. Adding SendGrid or Twilio means implementing that one function and
calling registerEmailProvider or registerSMSProvider; picking
a vendor is a config value (provider: 'aws-ses') or an environment
variable. Your application code — sendEmail, template, data — never
mentions the vendor, so swapping the delivery service is a registration and a config
line, not a rewrite.
sendEmail, sendSMS, sendSlack — template or direct content, phone numbers normalized to E.164.
AWS SES and SNS built in as optional deps; register your own with name + send().
Variable substitution with filters — currency, date, truncate, default — plus custom filters.
scheduleEmail and scheduleSMS via pg-boss; cancel by notification id.
In-process with concurrency control, or distributed across instances via pg-boss with per-item retry.
Store every notification; query by channel, status, recipient; per-channel stats.
Open pixel and click redirect with HMAC-signed tokens; open, click, and engagement analytics.
send* returns a SendResult instead of throwing; logs tagged per channel via @spfn/core/logger.