Channels

Lifecycle hooks

Observe sender activity without putting message bodies in hook context.

Hooks observe sends for metrics and tracing without coupling your application to a provider. Their contexts include delivery metadata, not a message body.

The one rule

Do not log message bodies in hooks; their contexts intentionally expose only delivery metadata.
import { createMailer } from "sently/mailer";
import { ResendTransport } from "sently/transports/resend";

const mailer = await createMailer({
  transport: new ResendTransport({
    apiKey: process.env.RESEND_API_KEY!,
  }),
  hooks: {
    onSuccess: ({ provider, subject, to }, result, durationMs) => {
      console.log(provider, subject, result.messageId, durationMs);
      console.log(to);
    },
  },
});
await mailer.send({
  from: "hello@example.com",
  to: "person@example.com",
  subject: "Welcome",
  text: "Thanks for joining.",
});

Hook callbacks

ChannelCallbacksContext
EmailonSend, onSuccess, onError, onRetry, onFallbackmessageId, recipients, subject, provider.
SMSonSend, onSuccess, onError, onRetry, onFallbackmessageId, recipient number, provider.
WhatsApponSend, onSuccess, onError, onRetry, onFallbackmessageId, recipient number, provider.
PushonSend, onSuccess, onError, onRetry, onFallbackmessageId, redacted endpoint / FCM token fingerprint, provider.

onSuccess receives the delivery result and optional duration in milliseconds. onError receives the error and optional duration.

Retry and fallback

onRetry runs only with RetryTransport. onFallback runs only with a fallback (or weighted fallback) transport. Wire either decorator around the channel transport you pass to createMailer, createSmsSender, createWhatsAppSender, or createPushSender.

Troubleshooting

Learn more

Next

On this page