When agents perform long-running tasks, users may go offline before the work completes. Rather than requiring users to keep their app open, agents can send push notifications to bring them back when results are ready.
Push notifications complement the online status capabilities of AI Transport. Use presence to detect when a user goes offline, then use push notifications to reach them on their devices when there's something to come back to.
When to use push notifications
Push notifications are suited to scenarios where there is a delay between a user's request and the agent's completion:
- Long-running agent tasks such as data analysis, report generation, or multi-step research that may take minutes to complete.
- Async workflows where users submit a request and move on, such as "generate a summary of this quarter's sales data and notify me when it's done".
- Background processing where agents continue work after users close their app, such as processing uploads, running batch operations, or monitoring for specific conditions.
If a user is still online when the agent completes work, deliver results directly through the channel. Push notifications are for reaching users who have already disconnected.
Set up push notifications
Before agents can send push notifications, the user's devices must be registered with Ably's push notification service.
Opt-in patterns
Users should have control over when they receive push notifications. There are two common opt-in patterns.
Per-session opt-in
Users can request a notification for a specific task. This is useful for tasks that are typically fast but occasionally take longer, where a blanket notification preference would be noisy.
The user sends a message to the agent indicating they want to be notified when the current task completes:
1
2
3
4
5
6
7
8
// Client code
const channel = ably.channels.get('big-bad-any');
// Request notification when the current task finishes
await channel.publish('request', {
prompt: 'Analyze last quarter\'s sales data and generate a report',
notifyOnComplete: true
});The agent reads this flag and stores the preference for the duration of the task:
1
2
3
4
5
6
7
// Agent code
let notifyUserOnComplete = false;
await channel.subscribe('request', (message) => {
notifyUserOnComplete = message.data.notifyOnComplete === true;
// Begin processing the task...
});App-wide opt-in
Users can enable notifications for all agent tasks through their app settings. The agent checks this preference before sending any notification. Store the preference in your application's user settings and pass it to the agent as configuration:
1
2
3
4
5
6
// Agent code
async function shouldNotifyUser(userId) {
// Check the user's notification preference from your application's settings
const userSettings = await getUserSettings(userId);
return userSettings.pushNotificationsEnabled === true;
}Sending notifications conditionally
Sending a push notification every time an agent completes work would be disruptive if the user is already looking at the results. Check the user's online status before deciding whether to send a push notification.
Check if the user is online
Use presence to determine if the user is still connected. If they are online, publish results to the channel as normal. If they are offline, send a push notification:
1
2
3
4
5
6
7
8
9
10
11
12
13
// Agent code
async function onTaskComplete(channel, userId, result) {
// Always publish results to the channel for history and connected clients
await channel.publish('result', result);
// If user is offline, also send a push notification
const members = await channel.presence.get();
const userIsOnline = members.some(m => m.clientId === userId);
if (!userIsOnline) {
await sendPushNotification(userId, channel.name, result);
}
}Multi-device awareness
A user may be connected on their desktop but not on their mobile phone. When the user has entered presence with device metadata, the agent can use this information to make smarter notification decisions.
For example, skip push notifications entirely if the user has any active device, or only send to mobile when the user is not on desktop:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Agent code
async function shouldSendPush(channel, userId) {
const members = await channel.presence.get();
const userDevices = members.filter(m => m.clientId === userId);
if (userDevices.length === 0) {
// User is completely offline, send push notification
return true;
}
// User has at least one active device, no push needed
// Results will be delivered via the channel
return false;
}Send a push notification
Use the Push Admin API to send a notification directly to a user by their clientId. The Realtime client exposes push.admin.publish(), so no separate REST client is needed. This delivers the notification to all devices registered to that user:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Agent code
var recipient = {
clientId: 'user-123'
};
var data = {
notification: {
title: 'Task complete',
body: 'Your sales report is ready to view'
},
data: {
channelName: 'session-abc-123',
type: 'task-complete'
}
};
ably.push.admin.publish(recipient, data);Notification payloads
Structure your notification payloads to give users enough context to decide whether to act immediately and to navigate directly to the relevant session when they do.
Deep linking
Include the channel name or session ID in the notification's data field so your app can navigate directly to the conversation when the user taps the notification:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Agent code
var recipient = { clientId: userId };
var data = {
notification: {
title: 'Research complete',
body: 'Your market analysis is ready'
},
data: {
channelName: channel.name,
sessionId: 'session-abc-123',
action: 'view-results'
}
};
ably.push.admin.publish(recipient, data);On the client side, read the data fields when handling the notification to navigate to the correct session:
1
2
3
4
5
6
// Client code - handling a push notification tap
function onNotificationTap(notification) {
const { channelName, sessionId } = notification.data;
// Navigate to the session and reattach to the channel
navigateToSession(sessionId, channelName);
}Completion summary
Include a meaningful summary of what completed in the notification body so users can triage without opening the app:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Agent code
const summary = generateSummary(result);
var recipient = { clientId: userId };
var data = {
notification: {
title: 'Report ready',
body: summary // For example: 'Q4 sales report: revenue up 12%, 3 action items identified'
},
data: {
channelName: channel.name,
sessionId: sessionId,
action: 'view-results'
}
};
ably.push.admin.publish(recipient, data);