@sathergate/notifykit
v0.1.0
Published
Unified notifications for Next.js. Any provider.
Downloads
62
Maintainers
Readme
notifykit
Unified notifications for Next.js. Any provider.
Send SMS, email, and push notifications through a single API. Provider-agnostic with adapters for Twilio, AWS SNS, Resend, and easy custom providers.
Install
npm install notifykitQuick Start
import { createHerald } from "notifykit";
import { createTwilioProvider } from "notifykit/adapters/twilio";
import { createResendProvider } from "notifykit/adapters/resend";
const herald = createHerald({
providers: [
createTwilioProvider({
accountSid: process.env.TWILIO_ACCOUNT_SID!,
authToken: process.env.TWILIO_AUTH_TOKEN!,
from: "+15551234567",
}),
createResendProvider({
apiKey: process.env.RESEND_API_KEY!,
from: "[email protected]",
}),
],
});
// Send an SMS
await herald.send({
to: "+15559876543",
channel: "sms",
body: "Your order has shipped!",
});
// Send an email
await herald.send({
to: "[email protected]",
channel: "email",
subject: "Order Confirmation",
body: "Thank you for your purchase.",
});Providers
Twilio (SMS)
import { createTwilioProvider } from "notifykit/adapters/twilio";
const twilio = createTwilioProvider({
accountSid: "AC...",
authToken: "your-auth-token",
from: "+15551234567",
});Uses the Twilio REST API directly via fetch. No SDK dependency.
AWS SNS (Push)
import { SNSClient, PublishCommand } from "@aws-sdk/client-sns";
import { createSNSProvider } from "notifykit/adapters/sns";
const sns = createSNSProvider(
{ region: "us-east-1" },
{ SNSClient, PublishCommand },
);You provide the AWS SDK classes. Herald stays lightweight.
Resend (Email)
import { createResendProvider } from "notifykit/adapters/resend";
const resend = createResendProvider({
apiKey: "re_...",
from: "[email protected]",
});Uses the Resend REST API directly via fetch. No SDK dependency.
Custom Provider
import type { NotificationProvider } from "notifykit";
const myProvider: NotificationProvider = {
channel: "sms",
async send(notification) {
// Your logic here
return { success: true, channel: "sms", messageId: "abc" };
},
};Templates
Define templates with {{variable}} placeholders:
const herald = createHerald({
providers: [twilio, resend],
templates: {
"order-shipped": {
channel: "sms",
body: "Hi {{name}}, your order #{{orderId}} has shipped!",
},
"welcome-email": {
channel: "email",
subject: "Welcome, {{name}}!",
body: "Thanks for joining us, {{name}}. Get started at {{url}}.",
},
},
});
await herald.notify("order-shipped", {
to: "+15559876543",
data: { name: "Alice", orderId: "12345" },
});React Hooks
import { HeraldProvider, useHerald, useNotification } from "notifykit/react";
function App() {
return (
<HeraldProvider herald={herald}>
<NotifyButton />
</HeraldProvider>
);
}
function NotifyButton() {
const { send, isSending } = useHerald();
return (
<button
disabled={isSending}
onClick={() =>
send({ to: "+15559876543", channel: "sms", body: "Hello!" })
}
>
Send SMS
</button>
);
}
function StatusAwareButton() {
const { send, status, error } = useNotification();
return (
<div>
<button
onClick={() =>
send({ to: "[email protected]", channel: "email", subject: "Hi", body: "Hello!" })
}
>
Send
</button>
{status === "sending" && <p>Sending...</p>}
{status === "sent" && <p>Sent!</p>}
{status === "error" && <p>Error: {error}</p>}
</div>
);
}Next.js API Routes
// app/api/notify/route.ts
import { createNotificationHandler } from "notifykit/next";
import { herald } from "@/lib/herald";
export const POST = createNotificationHandler(herald);// app/api/webhooks/notifications/route.ts
import { createWebhookHandler } from "notifykit/next";
export const POST = createWebhookHandler({
verify: (request, body) => {
// Verify webhook signature
return true;
},
onStatus: async (event) => {
console.log(`Message ${event.messageId}: ${event.status}`);
},
});Building Custom Providers
Implement the NotificationProvider interface:
import type { NotificationProvider, Notification, SendResult } from "notifykit";
export function createMyProvider(config: MyConfig): NotificationProvider {
return {
channel: "sms", // or "email" or "push"
async send(notification: Notification): Promise<SendResult> {
// Send the notification using your service
return {
success: true,
channel: "sms",
messageId: "unique-id",
};
},
};
}License
MIT
