Skip to Content
Dial v1 live 🎉
SdkNotifications

Notifications

Real-time push notifications for calls, messages, and voicemails across all platforms.

Setup

Request Permissions

const granted = await dial.notifications.requestPermissions(); if (granted) { console.log('Notifications enabled'); } else { console.log('Notifications denied'); }

Register for Push Notifications

await dial.notifications.register();

Notification Types

Call Notifications

// Incoming call dial.on('notification:call:incoming', (notification) => { console.log('Incoming call from:', notification.from); console.log('Call type:', notification.callType); // 'audio' | 'video' }); // Missed call dial.on('notification:call:missed', (notification) => { console.log('Missed call from:', notification.from); });

Message Notifications

dial.on('notification:message', (notification) => { console.log('New message from:', notification.from); console.log('Message preview:', notification.preview); });

Voicemail Notifications

dial.on('notification:voicemail', (notification) => { console.log('New voicemail from:', notification.from); console.log('Duration:', notification.duration); console.log('Transcription:', notification.transcription); });

Notification Object

interface Notification { id: string; type: 'call' | 'message' | 'voicemail'; from: string; // Wallet address timestamp: Date; title: string; body: string; data: any; // Type-specific data priority: 'high' | 'normal' | 'low'; }

Handling Notifications

Click/Tap Actions

dial.notifications.onClicked((notification) => { switch (notification.type) { case 'call': // Navigate to call screen navigateToCall(notification.data.callId); break; case 'message': // Navigate to chat navigateToChat(notification.from); break; case 'voicemail': // Navigate to voicemail navigateToVoicemail(notification.data.voicemailId); break; } });

Actions

// Add quick action buttons to notifications await dial.notifications.setActions({ call: [ { action: 'answer', title: 'Answer' }, { action: 'decline', title: 'Decline' } ], message: [ { action: 'reply', title: 'Reply' }, { action: 'mark_read', title: 'Mark as Read' } ] }); // Handle actions dial.notifications.onAction((action, notification) => { switch (action) { case 'answer': dial.calls.answer(notification.data.callId); break; case 'decline': dial.calls.decline(notification.data.callId); break; case 'reply': openQuickReply(notification.from); break; } });

Notification Preferences

Enable/Disable by Type

await dial.notifications.setPreferences({ calls: true, messages: true, voicemails: true, conferenceInvites: false });

Quiet Hours

await dial.notifications.setQuietHours({ enabled: true, start: '22:00', // 10 PM end: '08:00', // 8 AM timezone: 'America/New_York' });

Priority Contacts

// Always notify for these contacts, even during quiet hours await dial.notifications.setPriorityContacts([ '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb', '0x8ba1f109551bD432803012645Ac136ddd64DBA72' ]);

Sound & Vibration

await dial.notifications.setSound({ enabled: true, sound: 'default', // or custom sound URL vibrate: true, vibrationPattern: [0, 200, 100, 200] // ms });

Badge Count

// Get unread count const count = await dial.notifications.getBadgeCount(); console.log(`${count} unread notifications`); // Clear badge await dial.notifications.clearBadge();

Notification History

// Get notification history const history = await dial.notifications.getHistory({ limit: 50, unreadOnly: false }); // Mark as read await dial.notifications.markAsRead(notificationId); // Delete notification await dial.notifications.delete(notificationId); // Clear all notifications await dial.notifications.clearAll();

Platform-Specific Features

Web Push Notifications

// Request web push notification permission if ('Notification' in window && 'serviceWorker' in navigator) { const permission = await Notification.requestPermission(); if (permission === 'granted') { await dial.notifications.register(); } }

iOS (APNs)

// Handled automatically by iOS SDK // Configure in your app delegate: import DialSDK func application( _ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data ) { DialClient.shared.registerForPushNotifications(deviceToken: deviceToken) }

Android (FCM)

// Configure Firebase Cloud Messaging import wtf.dial.sdk.DialClient class MyFirebaseMessagingService : FirebaseMessagingService() { override fun onNewToken(token: String) { DialClient.getInstance().registerPushToken(token) } }

Rich Notifications

With Images

await dial.notifications.send({ to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb', title: 'Shared a photo', body: 'Check out this image!', image: 'https://example.com/image.jpg' });

With Inline Reply

// Enable inline reply for messages dial.notifications.onInlineReply((reply, notification) => { dial.messages.send({ to: notification.from, content: reply, type: 'text' }); });

Complete Example: Notification Manager

import { useState, useEffect } from 'react'; import { DialClient, Notification } from '@dial/sdk'; export function NotificationManager({ dial }) { const [notifications, setNotifications] = useState<Notification[]>([]); const [badgeCount, setBadgeCount] = useState(0); const [preferences, setPreferences] = useState({ calls: true, messages: true, voicemails: true }); useEffect(() => { setupNotifications(); loadNotificationHistory(); }, []); const setupNotifications = async () => { // Request permission const granted = await dial.notifications.requestPermissions(); if (granted) { await dial.notifications.register(); } // Listen for new notifications dial.on('notification:received', (notification) => { setNotifications(prev => [notification, ...prev]); setBadgeCount(prev => prev + 1); // Show browser notification if ('Notification' in window && Notification.permission === 'granted') { new Notification(notification.title, { body: notification.body, icon: '/icon.png' }); } }); // Handle notification clicks dial.notifications.onClicked((notification) => { handleNotificationClick(notification); markAsRead(notification.id); }); }; const loadNotificationHistory = async () => { const history = await dial.notifications.getHistory({ limit: 50 }); setNotifications(history); const count = await dial.notifications.getBadgeCount(); setBadgeCount(count); }; const handleNotificationClick = (notification: Notification) => { switch (notification.type) { case 'call': // Navigate to call break; case 'message': // Navigate to chat break; case 'voicemail': // Navigate to voicemail break; } }; const markAsRead = async (notificationId: string) => { await dial.notifications.markAsRead(notificationId); setNotifications(prev => prev.map(n => n.id === notificationId ? { ...n, read: true } : n ) ); setBadgeCount(prev => Math.max(0, prev - 1)); }; const updatePreferences = async (newPrefs: any) => { await dial.notifications.setPreferences(newPrefs); setPreferences(newPrefs); }; return ( <div className="notification-manager"> <div className="header"> <h2>Notifications</h2> {badgeCount > 0 && ( <span className="badge">{badgeCount}</span> )} </div> <div className="preferences"> <label> <input type="checkbox" checked={preferences.calls} onChange={(e) => updatePreferences({ ...preferences, calls: e.target.checked }) } /> Call notifications </label> <label> <input type="checkbox" checked={preferences.messages} onChange={(e) => updatePreferences({ ...preferences, messages: e.target.checked }) } /> Message notifications </label> <label> <input type="checkbox" checked={preferences.voicemails} onChange={(e) => updatePreferences({ ...preferences, voicemails: e.target.checked }) } /> Voicemail notifications </label> </div> <div className="notification-list"> {notifications.map(notification => ( <div key={notification.id} className={`notification ${notification.read ? 'read' : 'unread'}`} onClick={() => handleNotificationClick(notification)} > <div className="icon"> {notification.type === 'call' && '📞'} {notification.type === 'message' && '💬'} {notification.type === 'voicemail' && '🎙️'} </div> <div className="content"> <div className="title">{notification.title}</div> <div className="body">{notification.body}</div> <div className="time"> {notification.timestamp.toLocaleString()} </div> </div> {!notification.read && <div className="unread-dot" />} </div> ))} </div> </div> ); }

Testing Notifications

// Send test notification await dial.notifications.sendTest({ type: 'call', title: 'Test Call', body: 'This is a test notification' });

Next Steps

Last updated on