@notif-hub/sdk
v1.0.1
Published
TypeScript SDK for NotifHub push notification server
Maintainers
Readme
@notif-hub/sdk
Official JavaScript/TypeScript SDK for NotifHub - Multi-tenant push notification service with FCM and APNs support.
Installation
npm install @notif-hub/sdkQuick Start
import { NotifHubClient } from '@notif-hub/sdk';
const client = new NotifHubClient({
baseUrl: 'http://localhost:8080',
apiKey: 'your-api-key',
});
const app = client.app('your-app-id');
await app.notifications.sendToAll({
title: 'Hello World',
body: 'This is a test notification',
});Complete Usage Guide
1. Initialize Client
const client = new NotifHubClient({
baseUrl: 'http://localhost:8080',
apiKey: 'optional-api-key',
timeout: 30000, // optional, default 30s
retries: 3, // optional, default 3
});2. Apps Management
// Create app
const app = await client.apps.create({
name: 'My App',
slug: 'my-app',
});
// List apps
const { apps, total } = await client.apps.list();
// Get app
const app = await client.apps.get('app-id');
// Update app
await client.apps.update('app-id', {
name: 'Updated Name',
status: 'PAUSED',
});
// Delete app
await client.apps.delete('app-id');
// Update credentials
await client.apps.updateCredentials('app-id', {
fcmProjectId: 'my-project',
fcmServiceAccountEnc: JSON.stringify(serviceAccount),
apnsKeyId: 'ABC123',
apnsTeamId: 'TEAM123',
apnsTopic: 'com.myapp',
apnsEnvironment: 'PRODUCTION',
apnsKeyP8Enc: '-----BEGIN PRIVATE KEY-----...',
});3. Device Management
const appClient = client.app('app-id');
// Register device
await appClient.devices.register({
platform: 'IOS',
deviceToken: 'device-token-here',
userId: 'user-123',
tags: ['premium', 'beta'],
locale: 'en-US',
});
// List devices
const { devices, total } = await appClient.devices.list({
platform: 'IOS',
userId: 'user-123',
limit: 100,
});
// Get device
const device = await appClient.devices.get('device-id');
// Delete device (unsubscribe)
await appClient.devices.delete('device-id');4. Sending Notifications
// Send to all users
await appClient.notifications.sendToAll({
title: 'New Feature',
body: 'Check out our latest update',
data: { screen: 'features' },
});
// Send to specific devices
await appClient.notifications.sendToDevices(['device-1', 'device-2'], {
title: 'Hello',
body: 'Hello specific devices',
});
// Send to specific users
await appClient.notifications.sendToUsers(['user-1', 'user-2'], {
title: 'Hello Users',
body: 'Hello specific users',
}, {
platform: 'IOS', // optional
});
// Send to tags
await appClient.notifications.sendToTags(['premium', 'beta'], {
title: 'Premium Feature',
body: 'Check out our new feature',
}, {
match: 'all', // 'all' or 'any'
platform: 'ANDROID',
});
// Scheduled notification
await appClient.notifications.sendToAll({
title: 'Reminder',
body: 'Your appointment is tomorrow',
}, {
scheduledAt: '2025-12-31T23:59:59Z',
});
// Platform-specific options
await appClient.notifications.send({
payload: {
title: 'Platform Specific',
body: 'Different options per platform',
badge: 5,
sound: 'default',
ios: {
subtitle: 'iOS Only',
threadId: 'chat-1',
categoryId: 'MESSAGE_CATEGORY',
},
android: {
channelId: 'default',
icon: 'ic_notification',
color: '#FF0000',
},
},
target: { type: 'all' },
});
// Advanced iOS Features
await appClient.notifications.send({
payload: {
title: 'Time Sensitive Alert',
body: 'This notification bypasses Focus modes',
interruptionLevel: 'time-sensitive', // 'passive' | 'active' | 'time-sensitive' | 'critical'
mutableContent: true, // Enable notification service extensions
collapseId: 'chat-123', // Collapse multiple notifications
ttlSeconds: 3600, // 1 hour TTL
ios: {
pushType: 'alert',
priority: 'immediate',
imageUrl: 'https://example.com/image.png',
relevanceScore: 0.8, // For notification summary
targetContentId: 'screen://chat/123', // Deep linking
},
},
target: { type: 'all' },
});
// Critical Sound (iOS) - requires special entitlement
await appClient.notifications.send({
payload: {
title: 'Emergency Alert',
body: 'Critical notification with custom volume',
sound: {
name: 'emergency.aiff',
critical: true,
volume: 1.0, // 0.0 to 1.0
},
interruptionLevel: 'critical',
},
target: { type: 'users', userIds: ['user-1'] },
});
// Background Content Available (Silent Push)
await appClient.notifications.send({
payload: {
contentAvailable: true, // Silent push for background updates
data: { action: 'sync', timestamp: Date.now().toString() },
ios: {
pushType: 'background',
priority: 'throttled',
},
},
target: { type: 'all' },
});
// Android Rich Notifications
await appClient.notifications.send({
payload: {
title: 'New Message',
body: 'You have a new message',
android: {
channelId: 'messages',
priority: 'HIGH',
imageUrl: 'https://example.com/big-image.jpg',
icon: 'ic_message',
color: '#2196F3',
tag: 'chat-123', // Replace previous notification with same tag
clickAction: 'OPEN_CHAT',
},
},
target: { type: 'users', userIds: ['user-1'] },
});5. Notification Tracking
// Get notification status
const status = await appClient.notifications.getStatus('notification-id');
console.log('Sent:', status.stats.sent);
console.log('Errors:', status.stats.error);
// List notification history
const { notifications, total } = await appClient.notifications.list({
status: 'SENT',
limit: 50,
offset: 0,
});
// Get notification details
const notification = await appClient.notifications.get('notification-id');6. Templates
// Create template
await appClient.templates.create({
key: 'welcome',
title: 'Welcome {{name}}!',
body: 'Thanks for joining {{appName}}',
data: { type: 'welcome' },
ios: { sound: 'welcome.aiff' },
android: { channelId: 'welcome' },
});
// List templates
const { templates, total } = await appClient.templates.list();
// Get template
const template = await appClient.templates.get('welcome');
// Update template
await appClient.templates.update('welcome', {
title: 'Welcome aboard {{name}}!',
});
// Delete template
await appClient.templates.delete('welcome');7. API Keys
// Create API key
const apiKey = await appClient.keys.create({
name: 'Production Key',
roles: ['send'],
});
console.log('IMPORTANT: Save this key:', apiKey.key);
// List API keys
const { keys, total } = await appClient.keys.list();
// Delete API key
await appClient.keys.delete('key-id');Error Handling
import { NotifHubError } from '@notif-hub/sdk';
try {
await appClient.notifications.sendToAll({
title: 'Test',
body: 'Test message',
});
} catch (error) {
if (error instanceof NotifHubError) {
console.error('Error:', error.message);
console.error('Code:', error.code);
console.error('Status:', error.statusCode);
console.error('Details:', error.details);
}
}TypeScript Support
Full TypeScript support with comprehensive type definitions:
import type {
NotificationPayload,
Platform,
DeviceStatus,
NotificationStatusType,
} from '@notif-hub/sdk';
const payload: NotificationPayload = {
title: 'Hello',
body: 'World',
data: { key: 'value' },
};Complete Example
import { NotifHubClient } from '@notif-hub/sdk';
async function main() {
const client = new NotifHubClient({
baseUrl: 'http://localhost:8080',
});
// Create app
const app = await client.apps.create({
name: 'My App',
slug: 'my-app',
});
// Configure credentials
await client.apps.updateCredentials(app.id, {
fcmProjectId: 'my-project',
fcmServiceAccountEnc: JSON.stringify(serviceAccount),
});
// Get app client
const appClient = client.app(app.id);
// Register device
await appClient.devices.register({
platform: 'ANDROID',
deviceToken: 'fcm-token',
userId: 'user-1',
tags: ['premium'],
});
// Send notification
const result = await appClient.notifications.sendToUsers(['user-1'], {
title: 'Welcome',
body: 'Thanks for signing up!',
data: { screen: 'home' },
});
// Check status
const status = await appClient.notifications.getStatus(result.notificationId);
console.log('Sent to', status.stats.sent, 'devices');
}
main().catch(console.error);License
MIT
