August 16, 2023

Customizing the Connectifi Agent

Customizing the Connectifi Agent

The Connectifi Agent NPM module not only provides a default UX out of the box, but also a wide range of hooks for fully customizing the user experience to blend seamlessly with your platform's brand and interoperability strategy. To this end we've put together a collection of customization examples and open sourced them so that creating the perfect interoperability experience with Connectifi is now even easier!

A Custom Modal Intent Resolver
The same intent resolution using a custom 'context menu' style.

How to Customize the Connectifi Agent

Agent Configuration

The agent config is passed into the createAgent method which initiates the connection to the Connectifi cloud service. The config uses the AgentConfig type.

-- CODE language-js --
export interface AgentConfig {
   props?: FabProps;  
   headless?: boolean;
    logLevel?: LogLevel;
   bridgeGlobal?: boolean;
   handleIntentResolution?: (message: IntentResolutionMessage, callback: ResolveCallback, closeCallback: CloseCallback) => void;
    handleOpen?: (message: ConnectifiOpenMessage) => void;
   logger?: (...params: any) => void;
   onAuthError?: (directory: string) => void;
   onAppIdentityError?: (directory: string) => void;
   onChannelJoined?: (message: any) => void;
   onChannelLeft?: () => void;
   onConnected?: () => void;
   onDisconnected?: (nextConnect?: number) => void;
   onSignedIn?: (username: string) => void;
   onSignedOut?: () => void;
   onWorkingChanged?: (working: boolean) => void;
}

Top Level Properties

props

These are UI-specific properties that configure the default ‘FAB’ UX provided by the Agent (see UI Props below)

headless

If set to true - no default UI is rendered by the agent. The UI callbacks (below) can then be used to create a custom UX.

logLevel

logging can be set to ‘debug’, ‘info’, or ‘silent’

bridgeGlobal

This is an experimental feature. If set to true - the Agent will attach to the window.fdc3 object (e.g. if running in a desktop container) and join to it for intents resolution, channel membership, and context broadcasts.

logger

Specifies a custom function to output log statements.

UI Props

-- CODE language-js --
logoSrc?: string;
position?: ValidPositions;
loginStyle?: LoginStyles;

logoSrc

Defines a custom location for the logo shown in the FAB

position  

Positions the FAB in top, bottom, middle, and right/left/center of the screen.

loginStyle

Sets whether login dialogs will open in the same or a new window.

UI Callbacks

-- CODE language-js --
   handleIntentResolution?: (message: IntentResolutionMessage, callback: ResolveCallback, closeCallback: CloseCallback) => void;
    handleOpen?: (message: ConnectifiOpenMessage) => void;
   onAuthError?: (directory: string) => void;
   onAppIdentityError?: (directory: string) => void;
   onChannelJoined?: (message: any) => void;
   onChannelLeft?: () => void;
   onConnected?: () => void;
   onDisconnected?: (nextConnect?: number) => void;
   onSignedIn?: (username: string) => void;
   onSignedOut?: () => void;
   onWorkingChanged?: (working: boolean) => void;

handleIntentResolution

This function is called whenever a raiseIntent or raiseIntentsForContext call results in an ambiguous list of results for the end user to resolve.  The callback will be provided with an IntentResolutionMessage data structure, along with a function (ResolveCallback) to call when a user has selected  an app to route the intent to and a function (CloseCallback) called if the operation is ended without resolution (e.g. the end user closes the resolver dialog without making a selection).

-- CODE language-js --
export interface IntentResolutionMessage {
 resolutionType: ResolutionType;
 context: Context;
 data: AppIntentResult | AppIntentResult[];
 bridgeData?: AppIntentResult | AppIntentResult[];
}

The intent resolution message has the following properties:

resolutionType  

The type will be ‘intent-resolver’ or ‘context-resolver’ depending on if the resolution is coming from a raiseIntent or raiseIntentsForContext call.

context

The FDC3 context object associated with the intent

data

Either a single result (’intent-resolver’ type) or a list of results (’context-resolver’). See AppIntentResult below.

bridgeData

An optional set of results coming from the bridged fdc3 global context (Desktop Agent) if the bridgeGlobal property is set to true.  See AppIntentResult below.

onChannelJoined

Called when a channel is joined.  Argument is the id of the channel joined.

onChannelLeft

Called when leaveCurrentChannel is executed.  I.e. the user leaves the current channel but does not join another.

handleOpen

Called after fdc3.open is called or an intent results in launching a new app.  In this case, the service sends a message to the client requesting it to open the specific app.  The message format is as follows:

-- CODE language-js --
export interface ConnectifiOpenMessage {
 name?: string;
 url?: string;
 pendingId: string;
}

Where name is the name of the app in the directory, url is the url to launch (for web applications), and pendingId  is a nonce that will allow the newly launched app to retrieve any expected intent/context data.  Note: name and url are optional depending on the type of app being launched.

onWorkingChanged

Called when a request has been made to the service and when in flight requests have resolved and the Agent is no longer waiting.  The working argument passed to the function is a boolean indicating whether working as started or stopped.

onSignedIn

Called after the user has successfully signed into the directory.  Will be passed the username / identifier as an argument.

onSignedOut

Called after the user is signed out.

onConnected

Called when a socket connection is established.

onDisconnected

Called when the socket connection is dropped.  Will be passed the auto-reconnect time (in milliseconds) as an argument.

onAuthError

Called when the user could not connect to the directory because they could not be authenticated.  Passed the directory name as an argument.

onAppIdentityError

Called when the user could not connect to the directory because the app was not registered in the directory or the directory could not be found.  Passed the directory name as an argument.

Using the Examples

The examples in the Connectifi Getting Started repo provide detailed open source implementations of most of the above hooks. It's an open source project, so your feedback, use cases, and contributions are very welcome and appreciated!

And you can also find even more examples of how to use FDC3 API in the Connectifi FDC3 Sandbox.

Finally, if you've built something using FDC3 that you'd like to share, we'd love to hear about it and feature it in the Sandbox. Tell us about it at info@connectifi.co.