Skip to content

Actionable Notifications via Intent & Context #17

@kriswest

Description

@kriswest

This issue is a proposal to resolve:

via Intents and contexts, rather than proliferating new API calls within the Desktop Agent scope. This approach has the advantage that it might be implemented by a desktop agent (with optional rules in its resolver to router the intents to its internal handling) or by another app in the desktop (e.g. a custom Notification center implementation) at the discretion of the DesktopAgent provider / assembler.

The proposal draws inspiration from the Notifications Web API (see MDN and the Notification API Spec), but deviates from it in a few key areas. The notifications Web API allows for actionable notifications but they are performed by the application that generated the notification, which will use the data element and the action name to determine what action to take.

Whereas in FDC3 we are focused on application interoperability and our primary use case is to allow actions to be performed by other apps, through intents and contexts. Hence, the actions array is specified via the fdc3.action type (currently proposed in PR finos#779) which encapsulates an FDC3 context and an optional intent - allowing a range of actions with associated data to be specified, which can then be performed by other applications when sent to them via raiseIntent or raiseIntentForContext. This obviates the need for a data element in the notification.

Enhancement Request

Allow notifications to be raised via a standardized intent and context.

Use Case:

Actionable notifications are a common part of a suite of desktop applications. They are tied to application interop by the fact that they may be generated by one application or system but could or should be actioned via one or more other applications.

For example:
For example, An order management system (or a service monitoring one) might raise notifications for new orders, and offer you actions to ViewChart, ViewRisk or ViewHoldings via other applications.

Intents

There are several possible Intents that could be associated with notifications. The primary need for one is to create a notification, but you might also want to dismiss it (if actioned independently in the source app), subscribe to updates
as it changes state or subscribe to a (filtered) stream of notifications.

CreateNotification

Create a new notification using the supplied notification context.

UpdateNotification

Update or dismiss a particular notification, by passing an updated notification context with the id set.

GetNotifications

Retrieve or subscribe to a stream of notifications or updates about a particular notification.
Would require a context type describing a filter for notifications.

Contexts

fdc3.notification

To define the content of a notification and any options relating to how it should be handled or displayed.
May include actions that would be performed via FDC3 APIs (primarily raiseIntent, but could also be used
to broadcast context on a channel.

Draws inspiration from the Notification web API:

Details
Property Type Required Example Value
type string Yes 'fdc3.notification'
id.notificationId string No 'unique-value-123'
title string Yes 'Notification title displayed at top'
options object No see below
options.body string No "Text content of the notification displayed in its body"
options.icon string No https://www.example.com/example.png
options.image string No https://www.example.com/example.png
options.notificationType string No warning
options.actions array No see below
options.notificationAlertSound string No https://www.example.com/example.mp3
metadata object No see below
metadata.issuedAt datetime No "2022-03-30T15:44:44Z"
metadata.receivedAt datetime No "2022-03-30T15:44:44Z"
metadata.source AppIdentifier No { appId: "ABC", instanceId: "ABC123" }
metadata.timeout number No 600000
metadata.isRead boolean No false
metadata.isMuted boolean No false
metadata.isSnoozed boolean No false
metadata.isDeleted boolean No false

Examples

const notification = {
    type: 'fdc3.notification',

    /**
     * @optional
     * Identifiers for a notification. Might not be set when submitting a notification and applied by the
     * receiving system. Multiple identifiers might be used to link the notification to other systems that
     * generate or interact with it.
     */
    id: {
        notificationId: "uniqueIdentifier"
    },

    /**
     * @required
     * Defines a title for the notification, which is typically shown at the top of the notification window.
     */
    title: "string",

    /**
     * An options object containing any custom settings that you want to apply to the notification.
     * @see https://developer.mozilla.org/en-US/docs/Web/API/Notification/Notification
     */
    options: {
        /**
         * A string representing the body text of the notification, which is displayed below the title.
         */
        body: "Body content",

        /**
         * A string containing the URL of an icon to be displayed in the notification to attribute it.
         * If not specified a desktop agent might harvest this from the submitting applications
         * appD config.
         */
        icon: "https://...",

        /**
         * A string containing the URL of an image to be displayed in the body of the notification.
         * If not specified, this might be drawn from a templated notificationType (see below).
         */
        image: "https://...",

        /**
         * @optional
         * A classification for the notification that might be used to apply different templates and/or
         * filters to notifications.
         * Could use enumerated types: info | success | warning | error | debug
         * or free text...
         */
        notificationType: "warning",

        /**
         * A list of Actions that might be performed by a user interacting with the notification.
         * This is a key part of the relevance of Notifications to FDC3 as the actions can be loosely
         * coupled to applications that resolve them by defining them via intents and contexts. Hence,
         * though inspired by the Notifications web API we *should* depart from its spec here.
         * Encoded as an array of fdc3.action contexts as defined in PR #779
         * https://github.com/finos/FDC3/pull/779/files
         */
        actions: [
            {
                type:"fdc3.action",
                title: "View Contact",
                intent: "ViewContact",
                context: {
                    type: 'fdc3.contact',
                    name: 'Jane Doe',
                    id: {
                        email: 'jane@mail.com'
                    }
                }
            },
            {
                type:"fdc3.action",
                name: "Other actions", //No intent is specified, use findIntentByContext or raiseIntentForContext to handle
                context: {
                    type: 'fdc3.contact',
                    name: 'Jane Doe',
                    id: {
                        email: 'jane@mail.com'
                    }
                }
            }
        ],

        

        /**
         * A string containing the URL of an alert sound to play when the notification is received.
         */
        notificationAlertSound: "*.wav",
    },

    /**
     * Additional details about the notification - intended to be populated or used by the Desktop Agent
     * or the system receiving the notification, rather than the app raising the notification.
     * Not necessary for submitting a notification - but may be useful for other use cases
     * such as subscribing to a stream of filtered notifications or updates on a specific notification.
     */
    metadata: {
        /**
         * ISO8601 date formatted string.
         * When the notification was generated.
         */
        issuedAt: "2022-03-30T15:44:44Z",

        /**
         * ISO8601 date formatted string.
         * When the notification was received.
         */
        receivedAt: "2022-03-30T15:44:44Z", 

        /**
         * AppIdentifier representing the source application that generated the notification.
         */
        source: { appId: "ABC", instanceId: "ABC123" }, 

        /**
         * How long should the notification appear in a toast UI in millisecs?
         */
        timeout: 60000,

        /* Properties relating to the state of the notification. */
        isRead: false,
        isMuted: false,
        isSnoozed: false,
        isDeleted: false,
    }
}

//perform feature detection to determine if notifications are supported
const appIntent = await fdc3.findIntent("CreateNotification");
if (appIntent.apps.length > 0) {
    
    //Submit a notification
    const resolution = await fdc3.raiseIntent("CreateNotification", notification);
    
    //receive it back updated with ids and metadata
    const submittedNotification = await resolution.getResult();
    
    //update the notification after an action or status change
    submittedNotification.metadata.isSnoozed = true;
    await fdc3.raiseIntent("UpdateNotification", submittedNotification);
    
    //retrieve a stream of updates about a notification
    const filter = { type: "fdc3.notification.filter", id: { notificationId: "ABC123" } };
    const resolution2 = await fdc3.raiseIntent("GetNotifications", filter );
    const channel = await resolution2.getResult();
    channel.addContextListener("fdc3.notification", handlerFn);
    
    //retrieve a stream of notifications according to a filter
    const filter2 = { type: "fdc3.notification.filter", titleRegex: "(AAPL)/g", options: { type: "alert"} };
    const resolution3 = await fdc3.raiseIntent("GetNotifications", filter2 );
    const channel2 = await resolution3.getResult();
    channel2.addContextListener("fdc3.notification", handlerFn);

}

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions