Send Push Notifications
Send targeted push notifications across iOS, Android, and web platforms with advanced scheduling and personalization.
Sending Push Notifications
Send push notifications across multiple platforms with advanced targeting, personalization, and delivery optimization. Support for iOS, Android, and web push notifications with unified API.
Quick Start
Send your first push notification in minutes:
import { OMXClient } from '@omx-sdk/push-notification';
const omx = new OMXClient({
clientId: 'your_client_id',
secretKey: 'your_secret_key'
});
// Send a simple push notification
const result = await omx.pushNotification.send({
to: 'device_token_or_user_id',
title: 'Welcome to Our App!',
body: 'Thanks for installing our app. Get started now!',
// Platform-specific data
data: {
screen: 'onboarding',
userId: '12345'
}
});
console.log('Push notification sent:', result.messageId);Platform-Specific Notifications
Send notifications optimized for each platform:
// iOS-specific notification
const iosNotification = await omx.pushNotification.send({
to: 'ios_device_token',
// iOS-specific payload
ios: {
alert: {
title: 'New Message',
subtitle: 'From John Doe',
body: 'Hey, check out this amazing feature!'
},
badge: 1,
sound: 'default',
category: 'MESSAGE_CATEGORY',
// Rich notifications
mutableContent: true,
contentAvailable: true,
// Action buttons
actions: [
{ id: 'REPLY', title: 'Reply', type: 'textInput' },
{ id: 'VIEW', title: 'View', type: 'foreground' }
],
// Custom data
customData: {
conversationId: 'conv_123',
senderId: 'user_456'
},
// Media attachments
mediaUrl: 'https://yourapp.com/images/notification.jpg',
// Threading (group similar notifications)
threadId: 'messages_thread'
}
});
// Android-specific notification
const androidNotification = await omx.pushNotification.send({
to: 'android_registration_token',
// Android-specific payload
android: {
notification: {
title: 'New Message',
body: 'Hey, check out this amazing feature!',
icon: 'ic_notification',
color: '#4F46E5',
sound: 'default',
channelId: 'messages',
// Rich notifications
image: 'https://yourapp.com/images/notification.jpg',
// Action buttons
actions: [
{
action: 'REPLY',
title: 'Reply',
icon: 'ic_reply'
},
{
action: 'MARK_READ',
title: 'Mark as Read',
icon: 'ic_check'
}
]
},
// Data payload
data: {
conversationId: 'conv_123',
senderId: 'user_456',
type: 'message'
},
// Android-specific options
priority: 'high',
timeToLive: 86400, // 24 hours
collapseKey: 'messages',
// Direct boot mode
directBootOk: true
}
});
// Web push notification
const webNotification = await omx.pushNotification.send({
to: 'web_push_subscription',
// Web push payload
web: {
notification: {
title: 'New Message',
body: 'Hey, check out this amazing feature!',
icon: '/icons/notification-icon.png',
image: '/images/notification-banner.jpg',
badge: '/icons/badge.png',
// Interaction options
requireInteraction: true,
renotify: true,
tag: 'message_123',
// Action buttons
actions: [
{
action: 'reply',
title: 'Reply',
icon: '/icons/reply.png'
},
{
action: 'view',
title: 'View Message',
icon: '/icons/view.png'
}
],
// Custom data
data: {
conversationId: 'conv_123',
url: '/messages/conv_123'
}
},
// Web push options
options: {
ttl: 86400, // 24 hours
urgency: 'normal', // 'very-low', 'low', 'normal', 'high'
topic: 'messages'
}
}
});Bulk and Targeted Notifications
Send notifications to multiple recipients with advanced targeting:
// Send to multiple devices
const bulkNotification = await omx.pushNotification.sendBulk({
recipients: [
'device_token_1',
'device_token_2',
'device_token_3'
],
title: 'Flash Sale Started!',
body: 'Get 50% off everything. Limited time only!',
// Personalization for each recipient
personalizeData: true,
data: {
saleId: 'flash_sale_2024',
deepLink: '/sale'
}
});
// Send to user segments
const segmentNotification = await omx.pushNotification.sendToSegment({
segment: 'premium_users',
title: 'Exclusive Premium Feature',
body: 'New premium features are now available just for you!',
// Segment-specific customization
customization: {
premium_users: {
title: 'Exclusive Premium Feature',
icon: 'premium_icon'
},
regular_users: {
title: 'Upgrade to Premium',
icon: 'upgrade_icon'
}
}
});
// Geotargeted notifications
const geoNotification = await omx.pushNotification.sendGeoTargeted({
location: {
lat: 40.7128,
lng: -74.0060,
radius: 5000 // 5km
},
title: 'Special Local Offer!',
body: 'Visit our nearby store for an exclusive discount.',
// Location-specific data
data: {
storeId: 'store_nyc_001',
offerCode: 'LOCAL20',
storeAddress: '123 Main St, New York, NY'
},
// Delivery preferences
delivery: {
respectQuietHours: true,
timezone: 'America/New_York'
}
});
// Send based on user behavior
const behaviorNotification = await omx.pushNotification.sendToBehavior({
criteria: {
lastAppOpen: '> 7d', // Users who haven't opened app in 7 days
purchaseHistory: 'has_purchased',
engagementLevel: 'high'
},
title: 'We miss you!',
body: 'Come back and see what's new. You have exclusive offers waiting!',
// Re-engagement specific
data: {
campaignType: 're-engagement',
incentive: 'exclusive_offers',
deepLink: '/offers'
}
});Rich and Interactive Notifications
Create engaging notifications with rich media and interactive elements:
// Rich media notification
const richNotification = await omx.pushNotification.send({
to: 'device_token',
title: 'Your Order is Ready!',
body: 'Your pizza order #12345 is ready for pickup.',
// Rich media
media: {
type: 'image',
url: 'https://yourapp.com/images/pizza-ready.jpg',
alt: 'Delicious pizza ready for pickup'
},
// Interactive actions
actions: [
{
id: 'directions',
title: 'Get Directions',
type: 'foreground',
icon: 'directions_icon',
data: { action: 'open_maps' }
},
{
id: 'call_store',
title: 'Call Store',
type: 'background',
icon: 'phone_icon',
data: { action: 'call', phone: '+1-555-123-4567' }
},
{
id: 'track_order',
title: 'Track Order',
type: 'foreground',
icon: 'track_icon',
data: { action: 'track', orderId: '12345' }
}
],
// Progress tracking
progress: {
current: 4,
total: 4,
label: 'Ready for pickup'
}
});
// Carousel notification (multiple images/items)
const carouselNotification = await omx.pushNotification.send({
to: 'device_token',
title: 'New Arrivals Just for You!',
body: 'Swipe to see products we think you'll love.',
// Carousel content
carousel: [
{
image: 'https://yourapp.com/images/product1.jpg',
title: 'Wireless Headphones',
subtitle: '$99.99',
action: { type: 'deeplink', url: '/products/123' }
},
{
image: 'https://yourapp.com/images/product2.jpg',
title: 'Smart Watch',
subtitle: '$299.99',
action: { type: 'deeplink', url: '/products/456' }
},
{
image: 'https://yourapp.com/images/product3.jpg',
title: 'Bluetooth Speaker',
subtitle: '$79.99',
action: { type: 'deeplink', url: '/products/789' }
}
]
});
// Form input notification
const formNotification = await omx.pushNotification.send({
to: 'device_token',
title: 'Quick Feedback',
body: 'How was your recent order? Rate us!',
// Form elements
form: {
type: 'rating',
fields: [
{
id: 'rating',
type: 'rating',
label: 'Rate your experience',
max: 5,
required: true
},
{
id: 'comment',
type: 'text',
label: 'Additional comments',
placeholder: 'Tell us more...',
maxLength: 200
}
],
submitAction: {
type: 'webhook',
url: 'https://yourapp.com/feedback'
}
}
});
// Live activity notification (iOS)
const liveActivity = await omx.pushNotification.startLiveActivity({
userId: 'user_123',
activityType: 'food_delivery',
content: {
title: 'Pizza Delivery',
subtitle: 'Order #12345',
// Dynamic content
dynamicContent: {
status: 'preparing',
estimatedTime: '15 min',
driverName: null
},
// Static content
staticContent: {
orderNumber: '12345',
restaurant: 'Tony's Pizza',
items: ['Large Pepperoni Pizza', 'Garlic Bread']
}
},
// Update schedule
updateSchedule: 'real-time'
});
// Update live activity
await omx.pushNotification.updateLiveActivity(liveActivity.id, {
dynamicContent: {
status: 'on_the_way',
estimatedTime: '8 min',
driverName: 'Mike'
}
});Scheduled and Automated Notifications
Schedule notifications for optimal delivery times and automate based on triggers:
// Schedule notification for later
const scheduledNotification = await omx.pushNotification.schedule({
to: 'device_token',
title: 'Don't forget your appointment',
body: 'Your appointment is tomorrow at 2 PM.',
// Schedule for 1 hour before appointment
sendAt: '2024-01-20T13:00:00Z',
timezone: 'America/New_York',
data: {
appointmentId: 'apt_123',
reminderType: 'appointment'
}
});
// Send at optimal time for each user
const optimizedNotification = await omx.pushNotification.sendOptimized({
recipients: ['user_1', 'user_2', 'user_3'],
title: 'Weekly Summary',
body: 'Your weekly activity summary is ready!',
// AI-powered send time optimization
optimization: {
method: 'engagement_prediction', // When user is most likely to engage
fallbackTime: '10:00',
timezoneAware: true,
// Constraints
constraints: {
earliestTime: '08:00',
latestTime: '22:00',
respectQuietHours: true,
avoidWeekends: false
}
}
});
// Automated drip campaign
const dripCampaign = await omx.pushNotification.createDripCampaign({
name: 'Onboarding Sequence',
trigger: 'user_signup',
notifications: [
{
delay: 0, // Immediate
title: 'Welcome to YourApp!',
body: 'Thanks for joining us. Let's get you started!',
data: { screen: 'onboarding_step_1' }
},
{
delay: '1d', // 1 day later
title: 'Complete Your Profile',
body: 'Add a photo and preferences to personalize your experience.',
data: { screen: 'profile_setup' },
// Conditional sending
conditions: {
profileIncomplete: true
}
},
{
delay: '3d', // 3 days after signup
title: 'Discover Key Features',
body: 'Learn about the features that make us special.',
data: { screen: 'feature_tour' }
},
{
delay: '7d', // 1 week later
title: 'You're All Set!',
body: 'Congratulations on completing your setup!',
data: { screen: 'onboarding_complete' }
}
],
// Campaign settings
settings: {
respectUserTimezone: true,
preferredSendTime: '10:00',
pauseOnWeekends: false,
stopOnUninstall: true
}
});
// Behavior-triggered notifications
const behaviorTrigger = await omx.pushNotification.createBehaviorTrigger({
name: 'Cart Abandonment',
trigger: {
event: 'cart_updated',
conditions: {
cartValue: '> 50',
timeSinceUpdate: '> 30m',
userEngagement: 'high'
}
},
notification: {
title: 'Complete Your Purchase',
body: 'You have {{itemCount}} items waiting in your cart. Complete your order now!',
// Dynamic content based on cart
dynamicData: {
itemCount: '{{cart.itemCount}}',
cartValue: '{{cart.total}}',
firstItem: '{{cart.items[0].name}}'
},
actions: [
{
id: 'complete_purchase',
title: 'Complete Purchase',
type: 'foreground',
data: { screen: 'checkout' }
},
{
id: 'save_for_later',
title: 'Save for Later',
type: 'background'
}
]
},
// Frequency controls
frequency: {
maxPerDay: 1,
maxPerWeek: 3,
cooldownPeriod: '24h'
}
});Personalization and Localization
Personalize notifications with user data and localize for global audiences:
// Personalized notification
const personalizedNotification = await omx.pushNotification.send({
to: 'user_123',
// Template with placeholders
template: 'welcome_back',
// User-specific data
personalization: {
firstName: 'John',
lastVisit: '5 days ago',
favoriteCategory: 'Electronics',
loyaltyPoints: 1250,
// Dynamic recommendations
recommendations: await getUserRecommendations('user_123'),
// Location-based content
localOffers: await getLocalOffers(user.location),
// Behavioral data
streakDays: 7,
completedGoals: 3
},
// A/B test variants
variant: await getNotificationVariant('user_123', 'welcome_back_test')
});
// Multi-language notification
const localizedNotification = await omx.pushNotification.send({
to: 'device_token',
// Localized content
localizations: {
'en': {
title: 'New Message',
body: 'You have a new message from John.'
},
'es': {
title: 'Nuevo Mensaje',
body: 'Tienes un nuevo mensaje de John.'
},
'fr': {
title: 'Nouveau Message',
body: 'Vous avez un nouveau message de John.'
},
'de': {
title: 'Neue Nachricht',
body: 'Sie haben eine neue Nachricht von John.'
}
},
// Auto-detect user language or fallback
languageDetection: {
method: 'user_preference', // 'device_setting', 'user_preference', 'location'
fallback: 'en'
},
// Locale-specific formatting
formatting: {
currency: true,
datetime: true,
numbers: true
}
});
// Conditional content based on user segments
const segmentedNotification = await omx.pushNotification.send({
to: 'user_456',
// Different content for different user types
contentRules: [
{
condition: { userTier: 'premium' },
content: {
title: 'Exclusive Premium Offer',
body: 'Get 30% off your next premium purchase!',
icon: 'premium_crown'
}
},
{
condition: { userTier: 'standard' },
content: {
title: 'Special Offer',
body: 'Get 15% off your next purchase!',
icon: 'discount_tag'
}
},
{
condition: { isNewUser: true },
content: {
title: 'Welcome Bonus',
body: 'Get 20% off as a welcome gift!',
icon: 'gift_box'
}
}
],
// Fallback content
fallback: {
title: 'Special Offer',
body: 'Check out our latest deals!',
icon: 'default_offer'
}
});
// Dynamic content generation
const dynamicNotification = await omx.pushNotification.send({
to: 'user_789',
// Content generators
contentGenerators: {
title: async (user) => {
const weather = await getWeather(user.location);
return `Good ${getTimeOfDay()}, ${user.firstName}! It's ${weather.description} today.`;
},
body: async (user) => {
const recommendations = await getPersonalizedRecommendations(user.id);
return `We found ${recommendations.length} new items you might like!`;
},
data: async (user) => {
return {
weatherInfo: await getWeather(user.location),
recommendations: await getPersonalizedRecommendations(user.id),
localEvents: await getLocalEvents(user.location)
};
}
}
});Delivery Optimization
Optimize notification delivery for better engagement and user experience:
// Frequency capping
const frequencyCappedNotification = await omx.pushNotification.send({
to: 'user_123',
title: 'Daily Deals',
body: 'Check out today's amazing deals!',
// Frequency controls
frequencyCap: {
maxPerHour: 1,
maxPerDay: 3,
maxPerWeek: 10,
// Respect user preferences
respectUserSettings: true,
// Category-specific limits
categoryLimits: {
'promotional': { maxPerDay: 2 },
'transactional': { maxPerDay: 10 },
'marketing': { maxPerDay: 1 }
}
}
});
// Quiet hours and Do Not Disturb
const respectfulNotification = await omx.pushNotification.send({
to: 'user_456',
title: 'Important Update',
body: 'Your order status has been updated.',
// Delivery preferences
deliveryPreferences: {
// Respect user's quiet hours
quietHours: {
enabled: true,
start: '22:00',
end: '08:00',
timezone: 'user_timezone'
},
// Handle Do Not Disturb mode
doNotDisturb: {
respectDeviceSettings: true,
emergencyOverride: false, // Set to true for critical notifications
priorityThreshold: 'high'
},
// Weekend preferences
weekendDelivery: {
enabled: true,
differentTiming: true,
laterStartTime: '10:00'
}
}
});
// Smart delivery optimization
const smartNotification = await omx.pushNotification.sendSmart({
to: 'user_789',
title: 'Weekly Summary',
body: 'Your activity summary for this week is ready!',
// AI-powered optimization
smartDelivery: {
// Optimize send time based on user behavior
timeOptimization: {
enabled: true,
model: 'engagement_prediction',
factors: ['historical_opens', 'app_usage', 'timezone', 'day_of_week']
},
// Content optimization
contentOptimization: {
enabled: true,
testVariants: ['title_a', 'title_b'],
optimizeFor: 'open_rate'
},
// Delivery method optimization
channelOptimization: {
enabled: true,
alternatives: ['push', 'email', 'sms'],
selectBest: true
}
}
});
// Progressive delivery
const progressiveNotification = await omx.pushNotification.sendProgressive({
campaign: 'flash_sale_announcement',
title: 'Flash Sale Alert!',
body: '24-hour flash sale starting now. Up to 70% off!',
// Progressive rollout
rollout: {
strategy: 'percentage',
phases: [
{ percentage: 10, duration: '30m' }, // Test with 10% of users first
{ percentage: 50, duration: '1h' }, // If successful, expand to 50%
{ percentage: 100, duration: '2h' } // Full rollout
],
// Success criteria for progression
successCriteria: {
openRate: '> 0.15',
errorRate: '< 0.01',
uninstallRate: '< 0.001'
},
// Rollback conditions
rollbackConditions: {
errorRate: '> 0.05',
complaintRate: '> 0.01'
}
}
});
// Delivery retry logic
const reliableNotification = await omx.pushNotification.send({
to: 'device_token',
title: 'Payment Confirmation',
body: 'Your payment of $99.99 has been processed successfully.',
// Retry configuration for important notifications
retryPolicy: {
maxRetries: 3,
retryIntervals: ['5m', '30m', '2h'],
backoffStrategy: 'exponential',
// Retry conditions
retryConditions: [
'device_not_reachable',
'temporary_failure',
'rate_limited'
],
// Fallback channels
fallbackChannels: [
{ type: 'email', delay: '1h' },
{ type: 'sms', delay: '4h' }
]
}
});Error Handling and Monitoring
Handle delivery failures and monitor notification performance:
// Error handling
try {
const result = await omx.pushNotification.send(notificationData);
console.log('Notification sent:', result.messageId);
} catch (error) {
switch (error.code) {
case 'INVALID_TOKEN':
console.error('Device token is invalid or expired');
await omx.devices.markInvalid(error.deviceToken);
break;
case 'RATE_LIMITED':
console.log('Rate limited, retrying in:', error.retryAfter);
setTimeout(() => omx.pushNotification.send(notificationData), error.retryAfter * 1000);
break;
case 'QUOTA_EXCEEDED':
console.error('Daily quota exceeded');
await alerting.notifyAdmins('Push notification quota exceeded');
break;
case 'INVALID_PAYLOAD':
console.error('Notification payload is invalid:', error.details);
break;
case 'CERTIFICATE_ERROR':
console.error('iOS certificate error:', error.message);
await alerting.notifyAdmins('iOS certificate issue');
break;
default:
console.error('Notification sending failed:', error);
}
}
// Delivery status tracking
const deliveryStatus = await omx.pushNotification.getDeliveryStatus('msg_123');
console.log(deliveryStatus);
// {
// messageId: 'msg_123',
// status: 'delivered',
// deliveredAt: '2024-01-15T10:30:00Z',
// openedAt: '2024-01-15T10:35:00Z',
// platform: 'ios',
// deviceType: 'iPhone',
// attempts: 1,
// latency: 1.2 // seconds
// }
// Bulk delivery monitoring
const bulkStatus = await omx.pushNotification.getBulkDeliveryStatus('campaign_123');
console.log(bulkStatus);
// {
// campaignId: 'campaign_123',
// total: 10000,
// delivered: 9756,
// failed: 244,
// pending: 0,
// deliveryRate: 0.976,
// avgLatency: 2.1,
// errors: {
// 'invalid_token': 156,
// 'device_not_registered': 88
// }
// }
// Real-time monitoring
const monitor = omx.pushNotification.createMonitor({
events: ['sent', 'delivered', 'opened', 'failed'],
alerts: {
deliveryRate: { threshold: 0.95, email: 'alerts@yourapp.com' },
errorRate: { threshold: 0.05, slack: '#push-alerts' },
latency: { threshold: 5000, webhook: 'https://yourapp.com/alerts' }
}
});
monitor.on('alert', (alert) => {
console.log('Push notification alert:', alert);
handleAlert(alert);
});Best Practices
- Timing: Send notifications at optimal times for your users
- Frequency: Respect user preferences and avoid notification fatigue
- Personalization: Use user data to make notifications relevant
- Clear CTAs: Include clear calls-to-action in your notifications
- Testing: A/B test notification content and timing
- Monitoring: Track delivery rates and user engagement