Rich Notifications
Enhance notifications with images, action buttons, custom sounds, badges, deep links, priority, TTL. Rich notification fields, platform support, per-SDK action handlers.
Enhance your notifications with images, action buttons, and custom sounds.
Send Rich Notification#
Node.js SDK
import { AbrovaPush } from '@abrova/push-node';
const abrovaPush = new AbrovaPush({
apiKey: 'ab_live_your_api_key',
serverSecret: 'ab_srv_your_server_secret',
});
await abrovaPush.push.sendToUser({
userId: 'user_123',
title: 'New Product Available!',
body: 'Check out our latest arrival',
imageUrl: 'https://example.com/product.jpg',
iconUrl: 'https://example.com/icon.png',
actions: [
{ id: 'view', title: 'View Product', action: 'VIEW_PRODUCT' },
{ id: 'dismiss', title: 'Not Interested', action: 'DISMISS' }
],
data: {
productId: 'prod_123',
deepLink: '/products/prod_123'
}
});REST API
curl -X POST "https://push-api.abrova.ir/push/send-to-user" \
-H "x-api-key: ab_live_your_api_key" \
-H "x-server-secret: ab_srv_your_server_secret" \
-H "Content-Type: application/json" \
-d '{
"userId": "user_123",
"title": "New Product Available!",
"body": "Check out our latest arrival",
"imageUrl": "https://example.com/product.jpg",
"iconUrl": "https://example.com/icon.png",
"actions": [
{ "id": "view", "title": "View Product", "action": "VIEW_PRODUCT" },
{ "id": "dismiss", "title": "Not Interested", "action": "DISMISS" }
],
"data": {
"productId": "prod_123",
"deepLink": "/products/prod_123"
}
}'These rich notification fields work with all send endpoints: send (one device), send-to-user, send-to-devices, send-to-topic, send-to-segment, and broadcast. See REST API for all endpoints.
Rich Notification Fields#
| Field | Type | Description |
|---|---|---|
| imageUrl | string | Large image displayed in the notification (max 1MB) |
| iconUrl | string | Notification icon URL (used by Web notifications; the Android SDK uses its notificationIcon resource) |
| actions | array | Action buttons (max 3, enforced by the API) |
| deepLink | string | Deep link to open when the notification is tapped |
| sound | string | Custom sound file name or "default" |
| badge | number | App badge number (iOS only) |
| badgeAction | string | "set", "increment", "decrement" or "clear" |
| category | string | iOS notification category for action buttons |
| threadId | string | Thread identifier for grouping (iOS) |
| collapseKey | string | Key for collapsing multiple notifications |
| priority | string | "default", "high" or "low" |
| ttl | number | Time-to-live in seconds (Web push defaults to 86400 when omitted) |
Action Button Structure#
Each action needs an id and a title (max 20 characters). action is optional: Android passes it to your app as the deep link of the tap, and the Web service worker opens it as a URL. icon (Android icon name), destructive and authRequired (iOS) are optional too.
{
"actions": [
{
"id": "reply",
"title": "Reply",
"action": "REPLY_ACTION",
"icon": "reply_icon"
},
{
"id": "archive",
"title": "Archive",
"action": "ARCHIVE_ACTION",
"destructive": true
}
]
}Platform Support#
iOS
- Large images on notifications the SDK shows itself (foreground / real-time connection); background APNs notifications show no image, as the SDK's Notification Service Extension does not download it
- Up to 3 action buttons
- Badge number support
- Thread grouping
- Custom sounds (must be in app bundle)
Android
- Big picture style notifications
- Up to 3 action buttons
- Large image shown as the large icon when collapsed
- Notification channels
- Custom sounds (file name of a res/raw resource)
Handling Actions in SDKs#
Flutter
import 'package:abrova_push/abrova_push.dart';
AbrovaPush.onNotificationAction((event) {
print('Action tapped: ${event.actionId}');
print('Notification title: ${event.title}');
print('Notification data: ${event.data}');
switch (event.actionId) {
case 'view':
Navigator.pushNamed(context, '/product/${event.data?['productId']}');
break;
case 'dismiss':
// Handle dismiss
break;
}
});Android
Override onNotificationAction in your AbrovaPushCallback (see Callbacks):
import ir.abrova.push.sdk.AbrovaPush
import ir.abrova.push.sdk.AbrovaPushCallbackAdapter
import ir.abrova.push.sdk.AbrovaPushMessage
AbrovaPush.setCallback(object : AbrovaPushCallbackAdapter() {
override fun onNotificationAction(message: AbrovaPushMessage, actionId: String) {
Log.d("AbrovaPush", "Action tapped: $actionId")
Log.d("AbrovaPush", "Data: ${message.data}")
when (actionId) {
"view" -> {
val productId = message.data?.get("productId") as? String
// Navigate to product
}
"dismiss" -> {
// Handle dismiss
}
}
}
})iOS
Implement the AbrovaPushDelegate method (see Callbacks):
import AbrovaPushSDK
class PushHandler: NSObject, AbrovaPushDelegate {
func abrovaPush(_ abrovaPush: AbrovaPush, didReceiveNotificationAction action: NotificationAction, forMessage message: AbrovaPushMessage) {
print("Action tapped: \(action.id)")
print("Data: \(message.data ?? [:])")
switch action.id {
case "view":
if let productId = message.data?["productId"]?.value as? String {
// Navigate to product
}
case "dismiss":
break // Handle dismiss
default:
break
}
}
}
// Keep a strong reference: `delegate` is weak
let pushHandler = PushHandler()
AbrovaPush.shared.delegate = pushHandlerReact Native
import AbrovaPush from 'abrova-push-react-native';
AbrovaPush.onNotificationAction((event) => {
console.log('Action tapped:', event.actionId);
console.log('Title:', event.title);
console.log('Data:', event.data);
if (event.actionId === 'view') {
navigation.navigate('Product', { id: event.data?.productId });
}
});Web
The SDK's service worker handles notificationclick: it opens the clicked action's action URL (or the message deepLink) and reports the click to the page. Listen for it with onActionClicked:
abrovaPush.onActionClicked((actionId, message) => {
console.log('Action tapped:', actionId);
if (actionId === 'view') {
window.location.href = '/product/' + message.data?.productId;
}
});Image Requirements#
Large Image (imageUrl)
- Format: JPEG, PNG, GIF
- Max size: 1MB
- Recommended: 1024x512px (2:1 ratio)
- Must be HTTPS URL
Icon (iconUrl)
- Format: PNG (transparent)
- Max size: 256KB
- Recommended: 192x192px
- Used by Web notifications
Example: Rich Notification Payload#
{
"userId": "user_123",
"title": "Flash Sale! 50% Off",
"body": "Your favorite items are on sale for the next 2 hours",
"imageUrl": "https://cdn.example.com/sales/flash-sale-banner.jpg",
"iconUrl": "https://cdn.example.com/icons/sale-icon.png",
"sound": "sale_alert",
"badge": 1,
"priority": "high",
"ttl": 7200,
"collapseKey": "flash_sale",
"actions": [
{ "id": "shop_now", "title": "Shop Now", "action": "OPEN_SALE" },
{ "id": "remind_later", "title": "Remind Me", "action": "SET_REMINDER" }
],
"data": {
"saleId": "sale_flash_001",
"expiresAt": "2024-01-15T12:00:00Z",
"deepLink": "/sales/flash"
}
}