Denotes a field as being an action. Defining this field (with a non-undefined
value) will result in actions being
raised and sent back to the source application when the corresponding event happens.
For example, providing a value for the onClick
field of ButtonOptions will result in a
notification-action
event being fired when that button is clicked.
In the current version of the service, the NotificationActionResult
s returned back to an application are static
and must bedefined at the point where the notification is created. Later versions of the service will allow some
limited programmatic creation of these results, for use in situations where static result data isn't sufficient.
The generic parameters of this type are for future expansion. Future versions of the service will allow for more control over the handling of actions.
Data type used to represent the action result returned back to applications when an action is raised. Applications
capture these responses by adding a notification-action
listener. The contents of this type are entirely
application-defined, the only requirement is that the item is serializable by JSON.stringify
.
Since this type is entirely application-specific, the type is used in these definitions. However, there is an
optional generic argument here, which can be used if an application were to define its own conventions for the shape
of this field (which is recommended). To make use of this, define a notification-action
handler that includes the
application-defined type as a template argument. This type is then propogated up to NotificationActionEvent.
The example below demonstrates this, using the same use-case as at the top of this page.
interface MyAction = SnoozeAction | DetailsAction;
interface SnoozeAction {
task: 'schedule-reminder';
intervalMs: number;
}
interface DetailsAction {
task: 'view-calendar-event';
target: 'self'|'popup';
}
addEventListener('notification-action', (event: NotificationActionEvent<MyAction>)) => {
if (event.result.task === 'schedule-reminder') {
// 'event.result' will now be strongly-typed as an instance of SnoozeAction
scheduleReminder(notification.customData.eventId, Date.now() + result.intervalMs);
}
// Etc...
});
Actions are the mechanism through which notifications send messages back to the application that created them. The service defines a number of ways in which actions can be raised (a notification being interacted with by the user, being closed, expiring, etc.), and it is up to each application to decide if it wishes to be informed when each of these triggers occur.
For an action to be raised when one of these triggers occurs, the application must specify an action result for each trigger it is interested in. The application should then listen for when these actions are raised by listening for the
notification-action
event.This event is fired once each time an action is raised, and will contain the action result the application specified for that trigger. The application may then use the action result to determine which trigger occurred and respond appropriately.
If an action result is not specified for a particular trigger, or it is set to
null
, the application will not receive a correspondingnotification-action
when that trigger occurs.Unlike other event types,
notification-action
events will be buffered by the service until the application has added a listener for this event type, at which point it will receive all bufferednotification-action
events. The service will also attempt to restart the application if it is not running when the event is fired.For an overview of actions, consider the sample notification below:
import {addEventListener, create} from 'openfin-notifications'; // Create a notification with two buttons create({ // Basic info title: 'Reminder', body: 'Event "Weekly Meeting" is starting soon...', category: 'Upcoming Events', // We'll use the 'customData' field to store metadata about the event customData: {eventId: '12345'}, // We want the user clicking the notification to open the associated event, so register an 'onSelect' action onSelect: {task: 'view-calendar-event', target: 'popup'}, buttons: [ // A button that will schedule another reminder for 5 minutes from now. Since the application will be // responsible for snoozing the event, it will need to know about the user clicking this button. By setting // a NotificationActionResult for 'onClick', the service will raise a "notification-action" event when this // button is clicked, and will pass the value of 'onClick' as the 'result' field within the event { title: 'Snooze for 5 minutes', iconUrl: 'https://www.example.com/timer.png', onClick: { task: 'schedule-reminder', intervalMs: 5 * 60 * 1000 } }, // A button that closes the notification and doesn't prompt the user about this event again. Since the // application doesn't need to do anything when the user clicks this button, we leave 'onClick' undefined // rather than specifying a NotificationActionResult. This means that no action will be raised when the // button is clicked, and hence no "notification-action" event will be fired { title: 'Dismiss', iconUrl: 'https://www.example.com/cancel.png' } ] }); // Create a listener that will be called for each action // Note: This handler will be used for ALL actions, from ALL notifications that are created by this application. addEventListener('notification-action', (event: NotificationActionEvent) => { const {result, notification} = event; if (result['task'] === 'view-calendar-event') { // Open a window with full details of the associated event openEventDetails(notification.customData.eventId, result['target']); } else if (result['task'] === 'schedule-reminder') { // Schedule a new notification scheduleReminder(notification.customData.eventId, Date.now() + result['intervalMs']); } // Etc... });
The example above uses
customData
to store details about the notification subject (in this case, a calendar event), andonClick
actions to inform the application about how it should respond when the user interacts with the notification. This is our intended usage and recommended best-practice, but the service doesn't require applications to follow this convention - application developers are free to decide how to manage notification state.Within the
notification-action
handler, the application must be able to understand which notification is being handled, and how to decide what it should do next. The example above uses an application-definedaction
field to determine the correct action, but the notification'sid
,category
,customData
and other fields are also useful selectors.