Get Started

This tutorial will get you started writing an application for Verse. There is much more detailed documentation available here, but it’s not required to complete the tutorials.

 

What is the Verse Developer browser extension?

The Verse Developer browser extension is a tool for developers who are adding customised capabilities to IBM Verse. The tool allows an application to be registered with IBM Verse, where each application contains a set of customised capabilities. One or more applications can be registered using the tool. Each application can contain one or more extensions. In this tutoiral we will have a look at 2 of the possible types of extensions, templated links and widgets. To get a full list of the extension points supported by IBM Verse please go here.

Name Usage
Templated Link type = com.ibm.appreg.ext.templatedLink
Widget type = com.ibm.verse.ext.widget

As you will see in this tutorial extensions can be contributed to the following parts of the IBM Verse user interface:

  • Business Card
  • Mail Compose View
  • Mail Read View

 

What you are going to build

This tutorial starts with a sample application for you to add functionality to the Business Card in Verse. Then you will write another application that adds functionality to both the Mail Compose and Mail Read views.

 

What you’ll learn

  • How to add extensions into the Verse UI for your application.
  • How to transfer data from Verse to your application.

 

What you’ll need

  • Google Chrome or Firefox (minimum version 49.0) browser
  • Web Server for Chrome (alternatively, you can also use FireFox Thimble, or any other web server)
  • The Verse Developer Browser Extension source code
  • A text editor
  • Basic knowledge of HTML, CSS, JavaScript, and Chrome DevTools
  • Estimated time: 40 min

   

This tutorial gets you started on building an application for Verse. It does not go into the details of the API and different concepts. If you want to learn more, you can refer to the Documentation section, section at the end of the tutorial, but the readings are not required to finish this tutorial.

 

Note: The changes you make during the tutorial will only be applied to the Chrome browser that has the extension installed. To let other people test your Application, you will need to share the edited extension with them and let them install it on their Chrome browsers too. IBM will be providing an Application Registry to allow you to deploy your application in production.

How to Install

In this section, you will install the default Verse Developer browser extension and make it work with Verse. This Verse Developer browser extension already has one sample application, which contains one extension.

 

Download source code for Verse Developer Extension

  • Download the Verse Developer Browser Extension source code to your local file system by clicking here. Alternatively, you can fork the repository from here instead of downloading it.
  • Extract the folder at a location convenient to you.
  • After you have extracted the folder, locate the src folder. In this tutorial, you will modify the manifest.json and applications.json files from within the src folder.

 

We have also provided a tutorial_getting_started folder which contains four subfolders: step2, step3, step4, and step5. These subfolders contain the completed version of the files modified in each step of this tutorial.

 

Update manifest.json

In the src/manifest.json file there is a matches property, which contains an array of URLs. The extension will only run if the URL visited by the user matches one of the URLs listed in this array. If the Verse URL you are using is not listed in this array, update the manifest.json file to include it:

  • Open src/manifest.json file in a text editor.
  • See if the value for the property matches contains the URL you will be using for Verse. The * at the end of a URL means matching 0 or more characters. We recommend adding the *.
  • If your Verse URL is already there, proceed to the next step to install Verse Developer on either Google Chrome or Firefox. Otherwise, append the Verse URL you will be working with into the array as a string. Don’t forget to add a comma , at the end of the preceding URL before adding your own.

 

In code snippet below shows the manifest.json edited to include the https://mail.notes.collabservintegration.com/verse Verse URL

{
"name": "IBM Verse Developer Browser Extension",
"version": "1.0.0",
"manifest_version": 2,
"applications": { "gecko": {"id": "verse_dev_extension@ibm.com", "strict_min_version": "45.0"} },
"content_scripts": [ {
"js": [ "contentscript.js"],
"matches": [
"https://mail.notes.na.collabserv.com/verse*",
"https://mail.notes.ap.collabserv.com/verse*",
"https://mail.notes.ce.collabserv.com/verse*"
],
"run_at": "document_start"
}],
"web_accessible_resources": [
"page.js",
"applications.json",
"samples/templatedLink.html",
"samples/actions.html",
"custom-name-picker/index.html",
"hook-before-send/index.html"
]
}

 

Installing to Chrome

  • Open your Google Chrome browser, and type in the address bar: chrome://extensions.
  • Select Developer mode, (unpacked extensions can only be loaded in Developer mode.)
  • Click the button Load unpacked extension….
  • In the pop-up file picker, select the src folder, which contains the manifest.json file.
  • At this point, you should be able to see the IBM Verse Developer Browser Extension loaded into your chrome://extensions page.

Load Unpacked Extension

If you received an error related to Failed to load extension from: ... Manifest file is missing or unreadable, make sure you are loading the extension from the src folder, not its parent folder.

 

Installing to Firefox

  • Open your Firefox browser, and type in the address bar: about:debugging.
  • Select Load Temporary Add-On.
  • In the pop-up file picker, select the manifest.json file inside the src folder.
  • At this point, you should be able to see the IBM Verse Developer Browser Extension loaded into your about:debugging page.

Load Unpacked Extension

 

Reload Verse and test it out

  • Reload Verse, so that it will pick up the change you made to the extension.
  • Hover over a People bubble, and click on the i icon to bring up the business card.
  • Click on the arrow button located at the right bottom part of the business card to turn the card around.
  • At the back of the business card you will see a new link called Person Action.
  • Click on the Person Action link. This will load a web page in a popup window and display details of the messages that were sent from Verse to that page.

Load Unpacked Extension

 

How it works

If you have reached this step, congratulations! You successfully installed the Verse Developer Extension with one default application. But how does this all work?

 

An external application is registered with Verse via the file applications.json

[
{
"name": "Widget Samples",
"title": "Widget Sampled",
"description": "This samples demonstrates using the widget extension point",
"extensions": [
{
"name": "Person Action Sample",
"type": "com.ibm.verse.ext.widget",
"payload": {
"url": "${extensionPath}/samples/actions.html",
"features": [
"core"
],
"actions": [
{
"id": "com.ibm.verse.ext.person.action",
"object": "com.ibm.appreg.object.person",
"text": "Person Action",
"title": "Person Action",
"location": "window",
"renderParams": {
"width": "900",
"height": "500"
}
}
]
}
}
],
"services": [
"Verse"
]
}
]
  • The external application has id, name, title and description properties which are self explanatory.
  • The external application also declares a single extension of type com.ibm.verse.ext.widget which is used to integrate a third party web application.
  • The web application location is specified in the payload object via the url property.
  • For this sample the web application is a simple page which listens for messages from Verse and displays them.
  • The web page is loaded from within the browser extension as a web accessible resource, hence the url beginning with ${extensionPath}.
  • The web application must also send a com.ibm.verse.application.loaded message to Verse to signal that it has successfully loaded.
  • If the web application does not send a com.ibm.verse.application.loaded message to Verse within 30 seconds then Verse will display an error message to the user.
  • The extension declares one action which is bound to the com.ibm.appreg.object.person object, which means it displays on the back of all Verse business cards.
  • When this action is triggered it will open the associated web application in a new window which is 900 X 500 pixels in size.
  • The web application receives a message when the action is clicked with a context object which contains data about the person whose business card the action was triggered from.

 

To learn more about context objects and how they get sent, please refer to Verse API data and Sending and receiving data from Verse in the IBM Verse Extensibility section at the end of the tutorial.

 

In the next section, you will learn how to add further actions to the mail compose and mail read parts of the Verse UI.

Add Action for Mail Compose

In this section, you will add a new action which appear in the toolbar displayed when composing a mail i.e. Mail Compose view. When the user clicks on this action, the same external application will be opened. This extension point is very useful in cases where you want to display information relevant to a mail a user is currently composing e.g. you could use it to trigger the Watson Tone Analyser to provide the user with data on the tone of the mail before they send it.

 

Edit applications.json

  • Open src/applications.json in your text editor.
  • Append the following object into the actions array in applications.json, and save the file.

    ⚠️ Don’t forget to add a comma , at the end of the preceding action before adding this one.

{
"id": "com.ibm.verse.ext.mail.compose.action",
"path": "mail.compose",
"text": "Mail Compose Action",
"title": "Mail Compose Action",
"location": "window",
"renderParams": {
"width": "900",
"height": "500"
}
}
  • Your file applications.json should now look like this:
[
{
"name": "Widget Samples",
"title": "Widget Sampled",
"description": "This samples demonstrates using the widget extension point",
"extensions": [
{
"name": "Person Action Sample",
"type": "com.ibm.verse.ext.widget",
"payload": {
"url": "${extensionPath}/samples/actions.html",
"features": [
"core"
],
"actions": [
{
"id": "com.ibm.verse.ext.person.action",
"object": "com.ibm.appreg.object.person",
"text": "Person Widget Action",
"title": "Person Widget Action",
"location": "window",
"renderParams": {
"width": "900",
"height": "500"
}
},
{
"id": "com.ibm.verse.ext.mail.compose.action",
"path": "mail.compose",
"text": "Mail Compose Action",
"title": "Mail Compose Action",
"location": "window",
"renderParams": {
"width": "900",
"height": "500"
}
}
]
}
}
],
"services": [
"Verse"
]
}
]

 

Reload the extension and Verse

Every time you make a change to the extension code, you need to reload the extension first, then reload Verse, so that your browser and Verse will pick up your latest changes.

  • To reload the extension in Chrome, open your Chrome browser, go to chrome://extensions, find the IBM Verse Developer Browser Extension, and click Reload.
  • In the pop-up Mail Compose view, click on the More actions button.
  • In the drop-down menu, click Mail Compose Action. This will bring up the web application you just registered with the browser extension, with information related to the Mail Compose view passed on from Verse.

 

Load Unpacked Extension

Congratulations! You successfully added a button to the Mail Compose view, and registered the relevant application with Verse.

 

How it works

  • This action uses the path property to specify were it is displayed in the Verse UI
  • Using mail.compose as the path will cause the action to be displayed in the toolbar in the mail compose window
  • The action will also be available when replying to or forwarding a mail
  • The action is always displayed in the “More actions” dropdown menu of the toolbar

Add Action for Mail Read

In this section, you will add an action which will display when the user is reading a mail i.e. the Mail Read view. When the user clicks on this action, the same external application will be opened. This extension point is very useful for cases where you want to transfer received mails from Verse to another application e.g. you could use this to post a mail to Watson Workspace.

 

Edit applications.json

  • Open src/applications.json in your text editor.
  • Append the mail read action object into the com.ibm.verse.sample.ext.widget.mail.actions extension belonging to the application with id: com.ibm.verse.sample.app.widget, and save the file.

    ⚠️ Don’t forget to add a comma , at the end of the preceding action object before adding your own.

{
"id": "com.ibm.verse.ext.mail.read.action",
"path": "mail.read",
"text": "Mail Read Action",
"title": "Mail Read Action",
"location": "window",
"renderParams": {
"width": "900",
"height": "500"
}
}

Your file applications.json should look something like this:

[
{
"name": "Widget Samples",
"title": "Widget Sampled",
"description": "This samples demonstrates using the widget extension point",
"extensions": [
{
"name": "Person Action Sample",
"type": "com.ibm.verse.ext.widget",
"payload": {
"url": "${extensionPath}/samples/actions.html",
"features": [
"core"
],
"actions": [
{
"id": "com.ibm.verse.ext.person.action",
"object": "com.ibm.appreg.object.person",
"text": "Person Widget Action",
"title": "Person Widget Action",
"location": "window",
"renderParams": {
"width": "900",
"height": "500"
}
},
{
"id": "com.ibm.verse.ext.mail.compose.action",
"path": "mail.compose",
"text": "Mail Compose Action",
"title": "Mail Compose Action",
"location": "window",
"renderParams": {
"width": "900",
"height": "500"
}
},
{
"id": "com.ibm.verse.ext.mail.read.action",
"path": "mail.read",
"text": "Mail Read Action",
"title": "Mail Read Action",
"location": "window",
"renderParams": {
"width": "900",
"height": "500"
}
}
]
}
}
],
"services": [
"Verse"
]
}
]

 

Reload the extension and Verse

As explained in the previous section, every time you make a change to the extension code, you need to reload the extension then reload Verse, so that the browser and Verse will pick up your latest changes.

Test it out

  • In the Mail Read view, click on the More actions button.
  • In the drop-down menu, click Mail Read Action. This will bring up the web application you just registered with the browser extension, with information related to the Mail Read view passed on from Verse.

 

Load Unpacked Extension

Congratulations! You successfully added an action button to the Mail Read view, and registered it as a new extension for the Mail Read application that you created in the last section.

 

How it works

  • This action also uses the path property to specify were it is displayed in the Verse UI
  • Using mail.read as the path will cause the action to be displayed in the toolbar in the mail preview area
  • The action is always displayed in the “More actions” dropdown menu of the toolbar

Secure the Application

The sample applications we have worked with so far are not secure because they do no check the origin of messages they receive. It is your responsibility to protect your application against cross-site scripting attacks.

 

The following version of the actions.js includes a check to verify the validity of the message origin. The method isValidOrigin contains a list of origins which the application expects to receive messages from. Messages from other origins are possible cross-site scripting attacks. This list of origins that are checked should be the same as the ones listed in the manifest.json.

 

/**
* Print out Verse API data for all the action samples
*/
window.addEventListener("message", function(event) {
if (!isValidOrigin(event.origin)) {
return;
}

document.getElementById("status").innerHTML = "";

var jsonNode = document.getElementById("json");
jsonNode.innerText = jsonNode.innerText + "\n" + JSON.stringify(event.data, null, 2);

/**
* Message from Verse to check whether your web application is ready.
*/
if (event.data.verseApiType === "com.ibm.verse.ping.application.loaded") {
var loaded_message = {
verseApiType: 'com.ibm.verse.application.loaded'
};
/**
* Your application must send a message back to Verse
* to identify that it's ready to receive data from Verse.
*/
event.source.postMessage(loaded_message, event.origin);
}
}, false);

/**
* Verify we are listening to the right origin
* @param {String} currentOrigin - The url which we should listen to
* @return {Boolean} true if the origin is valid, false otherwise
*/
function isValidOrigin(currentOrigin) {
var originsList = [
"https://mail.notes.na.collabserv.com",
"https://mail.notes.ap.collabserv.com",
"https://mail.notes.ce.collabserv.com"
];
for (var i = 0; i < originsList.length; i++) {
if (originsList[i].indexOf(currentOrigin) !== -1) {
return true;
}
}
return false;
}

Create a New Application

The previous sections showed you how to register an application with Verse, add a widget extension and then add multiple actions to the Verse UI. The external application that was launched was hosted within the Verse Developer Browser Extension. This is very convenient when developing a very simple page but a real application will need to be hosted elsewhere.

 

Set up a web server

If you are familiar with setting up your own server for hosting web pages please add src/samples/templatedLink.html and src/sample/templatedLink.js to your server and then skip to the next step.

 

Otherwise, you can use the Chrome Web Server to set up a localhost on your machine by following these steps:

  • Install the Chrome Web Server from the Chrome Web Store using your Chrome browser.
  • After installing, launch it by navigating to chrome://apps in your Chrome browser, and clicking on the icon for the Chrome Web Server.
  • After the application is launched, click the choose folder button and select the src folder of the Verse Developer Web Extension.
  • Toggle the Web Server: STARTED button to stop, then restart the web server. Once the server is started (indicated by a blue color on the button), you can access sample html files by clicking on the link provided under the Web Server URL(s) section, or by typing that address into the browser.

 

Load Unpacked Extension

 

The web page you will use in this step is the templatedLink.html.

 

Edit applications.json

For this step we are going to remove the application we worked on in the previous steps and add a new one. Edit the applications.json file so that it contains the following content:

 

[
{
"name": "Templated Link Sample",
"title": "Templated Link Sample",
"description": "This samples demonstrates using the templated link extension point",
"extensions": [
{
"name": "Person Templated Link",
"type": "com.ibm.appreg.ext.templatedLink",
"object": "com.ibm.appreg.object.person",
"payload": {
"text": "Templated Link Action",
"title": "Templated Link Action",
"href": "http://127.0.0.1:8887/samples/templatedLink.html?searchFor=${profile.primaryEmail}"
}
}
],
"services": [
"Verse"
]
}
]

 

Test it out

  • Now try it out in Verse: first reload the extension and then reload Verse to pick up your latest code changes.
  • Hover over a People bubble, and click on the i icon to bring up the business card.
  • Click on the arrow button located at the right bottom part of the business card to turn the card around.
  • At the back of the business card you will see a new link called Person Templated Link.
  • Click on the Person Templated Link link. This will load the associated web page in a new tab and will display the email address of the person whose business card was opened.

 

Load Unpacked Extension

 

How it works

  • This step introduces a new extension point with the type com.ibm.appreg.ext.templatedLink
  • A templated link is used to invoke a web application and data is passed is parameters in the URL query string
  • Parameters are specified using the ${<parameter>} notation where the parameter is a json path relative the the context data
  • The location of the web application is specified using the href property
  • If the protocol used by the web application is http or https then it is opened in a new browser tab, otherwise it is opened in a hidden iframe

IBM Verse Extensibility

Verse Extensibility allows you to integrate your own web applications with IBM Verse, by registering your application with it. Your application can declare one or more extensions, which will enhance Verse with new functionality.

For example, one of the extension points that Verse supports is a templated link extension. A templated link extension is displayed as a link in the Verse User Interface (UI) which, when clicked, opens a URL to a third party web application.

An extension can declare that it requires specific data from Verse, and when the extension is activated, Verse will send this data to it. For example, if you add a templated link to a Verse business card, your extension can be configured to receive the email address of the person included in the link URL.

Extensibility Concepts

This section introduces extensibility concepts and terminology that is used throughout this document.

  • Application: A third-party web application that contributes new functionality to IBM Verse. An application can contribute one or more new features to different parts of the IBM Verse UI.
  • Extension: A feature that contributes to a specific part of IBM Verse. For example, an extension that adds a button or link to the Verse UI which, when clicked, opens a new browser window containing a third-party web application. The URL of the application is registered with Verse and the application opens in a separate window. The application has access to Verse data through cross-document messaging or URL query string parameters.
  • applications.json: This file contains the details of your application: where in the Verse UI your extensions will appear, how your application communicates with Verse, etc. See the applications.json section for more information.

IBM Verse Container

IBM Verse Container allows applications to contribute or remove UI at specific locations within the container. Path and Object are the ways the container provides the ability to target a location.

 

Path

IBM Verse allows extensionss to contribute or remove UI at specific locations in Verse. A path is one way the container provides the ability to target a location. Here is an example of 2 supported paths:

  • mail.read - allows application developers to contribute an action under more actions button when viewing an existing email
  • mail.compose - allows application developers to contribute an action under more actions button when composing a new email

 

Object

Another way for a container to allow extensions to target locations is by an objecttype. IBM Verse also supports an extension to add a button on Person object. For example, an extension is contributed to the bizcard cards which has a person object. Here is an example of a supported object:

  • Person (type = com.ibm.appreg.object.person)

Verse Extension Points

IBM Verse supports the general extension points defined by appregistry, like the Simple Link and Templated Link. Besides that, Verse also supports to contribute a Widget extension to add some Widget Actions to Verse UI page. For example, a widget can contribute an action to More Actions… menu in toolbar when composing/viewing a message, or contribute an action to Verse business card.

For a simple and templated link type extension, it will be rendered as a plain link on the Verse UI. Therefore, when a link type extension clicks, it will be open in a new tab/window.

Simple Link and Templated Link extensions provide an easy way to contribute clickable UI artifacts that result in the opening of a webpage in a new tab/window.

However, Widget Action’s inside of Widget’s allow those same kinds of clickable UI artifacts to trigger programmatic logic inside of widgets, which are like mini web applications that can respond to that input.

Here is the full list of extension points that Verse supports:

 

A Simple Link extension adds a clickable URL link to the Verse UI.

 

  • {string} text The text for the link
  • {string} href The link location

 

  • {string} icon An icon to use when rendering the link. The only value format supported for this property is a data-uri with a base64 encoded payload.
  • {string} alt Alt text for the link.

 

{
"type": "com.ibm.appreg.ext.simpleLink",
"object": "com.ibm.appreg.object.person",
"payload": {
"text": "Click this sample link!",
"href": "https://sample.com/simple-link-target.html",
"icon": "data:image/png;base64,..."
}
}

   

A Templated Link extension adds a clickable URL link to the Verse UI including the option to configure the extension to receive data from Verse encoded in the URL.

 

Templating Syntax

Values contained within the extension that have text of the format ${property} will be replaced with the value keyed by property from the context of the bound object.

 

Templating Syntax of plural-fields

Values contained within the extension that have text of the format ${property.type} will be replaced with the value within the plural-field keyed by property which has the type ‘type’ from the context of the bound object.

If there are multiple values within the plural-field keyed by property that have type type, preference will be given to the value of type type that is “primary”. If there is no “primary” within the set of plural-field values of type ‘type’, it is up to the Container’s discretion to determine which value is returned.

If no type is specified and the specified property keys a plural-field value, the primary entry of the plural-field will serve as the replacement value.

 

EX: emails is a plural field

{
emails: [
{
type: 'work',
primary: false,
value: altwork@DOMAIN.COM
},{
type: 'home',
primary: false,
value: home@DOMAIN.COM
},{
type: 'home',
primary: true,
value: primaryhome@DOMAIN.COM
},{
type: 'work',
primary: false,
value: work@DOMAIN.COM
}
]
}

${emails} -> primaryhome@DOMAIN.COM //The primary value

${emails.work} -> altwork@DOMAIN.COM //The first occurrence of type "work" (container's disgression)

${emails.home} -> primaryhome@DOMAIN.COM //The primary value for type "home" (primary is of type "home")

 

  • {string} text The text for the link
  • {string} href The link location. Verse will take care to URL encode values replaced in the href property.

 

  • {string} icon An icon to use when rendering the link. The only value format supported for this property is a data-uri with a base64 encoded payload.
  • {string} alt Alt text for the link.
  • {string} locator A hint for container where to render the link within the UI representation of the binding object. Verse currently does not use the locator property.

 

{
"type": "com.ibm.appreg.ext.templatedLink",
"object": "com.ibm.appreg.object.person",
"payload": {
"text": "Look up ${displayName} in the directory!",
"href": "https://sample.com/simple-link-target.html?user=${emails.work}",
"icon": "data:image/png;base64,...",
"locator": "profile"
}
}

   

Widget (com.ibm.verse.ext.widget)

A Widget extension associates a third party web application with Verse by opening a new browser window/tab or embedding the application using an iframe within the Verse UI. A widget extension may contribute multiple Widget Actions to the Verse UI.

All of actions in the widget will share the same url. When Widget Action is clicked, the application opened by the widget’s url will be rendered on the different place based on the action’s location.

 

Widget Definition

The definition of a widget MAY contain 1 or multiple Widget Actions. The Widget Actions can also be dynamically added to a widget.

 

Required Properties for a Widget

  • {string} url The widget’s url, when the action in the widget is clicked, the widget will open the url on the place specified by the action’s location.
  • {array} actions An array of Widget Actions. This property identifies the contributed Widget Actions by this widget.

 

Optional Properties for a Widget

  • {array} features An array of strings. The property is used to specify what features provided by the container are used by this application. Each feature maps to a set of APIs provided by the container. If the application needs to use certain APIs, it needs to add the corresponding feature to this property. The supported features are listed below.
    • core - that means the widget needs to communicate with Verse page via cross document messaging.

 

Example Widget

In this sample, a widget contains two actions, one action is contributed under More actions button when viewing an existing email and the second action is contributed under More actions button when composing a new email. When the actions are clicked, the widget will be rendered on the new window which width and height are both 800px.

 

{
"type": "com.ibm.verse.ext.widget",
"payload": {
"url": "https://sample.com/widget.html",
"features": ["core"],
"actions": [
{
"id": "com.ibm.verse.widget.action.mailRead1",
"path": "mail.read",
"text": "Click this action",
"icon": "data:image/png;base64,...",
"location": "window",
"renderParams": {
"width": "800",
"height": "800"
}
},
{
"id": "com.ibm.verse.widget.action.mailCompose1",
"path": "mail.compose",
"text": "Click this action",
"icon": "data:image/png;base64,...",
"location": "window",
"renderParams": {
"width": "800",
"height": "800"
}
}
]
}
}

 

Widget Action

A widget action is a UI component which will be contributed to Verse page. An action MUST be contained in a widget extension, it can’t be directly added into Applications extensions array.

When a contributed action is clicked, the widget will be rendered in a different place based on the location value.

 

Required Properties for a Widget Action

  • {string} id The id for the action.
  • {string} text The text for the action.
  • {string} path The path identifies where the action is contributed. All of supported paths are listed here.

 

Optional Properties for a Widget Action

  • {string} icon An icon to use when rendering the action. Containers MAY choose to not honor this attribute for any reason, for example: if it would be inappropriate to render an icon in the location it was contributed to. The preferred format for the icon is a data-uri.
  • {string} alt Alt text for the action.
  • {object} location The property is used to specify where to render the widget. The acceptable values can be window, tab or embedded.
    • window - the widget will be open in the new window. We can use renderParams to specify the new window’s size.
    • tab - the widget will be open in the new tab.
    • embedded - the widget will be open inside an iframe. This value is only supported for Mail Compose actions.
  • {object} renderParams The property is used to specify the window size when the application is open in a new window. The renderParams property contains width and height properties which are used to specify the new window’s width/height accordingly. This property is only valid if the location’s value is window.

 

Example Widget Action

{
"id": "com.ibm.verse.widget.action.mailCompose",
"path": "com.ibm.verse.path.mailCompose",
"text": "Click this action",
"icon": "data:image/png;base64,...",
"location": "window | tab | embedded",
"renderParams": {
"width": "800",
"height": "600"
}
}

   

Name Picker (com.ibm.verse.ext.namePicker)

The Name Picker extension point allows the integration of a custom UI for selecting addresses when sending an email. When a custom name picker is contributed to Verse, the ‘To’ label in the UI for composing a mail will be rendered as a link. On clicking the link, the name-picker will be rendered inside of the mail compose view. The user can select names using the name pickerand these will be added to whichever of To, Cc or Bcc input fields is currently selected.

 

Required Properties for a Name Picker

  • {string} url The widget’s url, when the To link is clicked, a new iframe will open in the mail compose view pointing to this URL. The resource at the URL must display a UI allowing the user to add names to the email.

 

Example Name Picker

{
"name": "Custom name picker",
"title": "Name Picker",
"description": "Custom name picker on mail compose",
"extensions": [
{
"type": "com.ibm.verse.ext.namePicker",
"name": "Custom name picker in mail compose",
"url": "${extensionPath}/custom-name-picker/index.html",
"title": "Add Contact"
}
],
"payload": {},
"services": [
"Verse"
]
}

   

Before On Send (com.ibm.verse.ext.beforeOnSend)

The Before On Send extension point allows third party logic to be invoked which can validate the content of an email. The extension can either display a UI e.g. to warn the user about something in the mail or can allow the mail to be sent. By default if an extension displays a UI with a warning the user can decide to send the mail anyway by clicking the send button again.

An optional property called disableSend is provided to control the send button behavior. By default disableSend is set as false, which means that send button will always be enabled and the user can send the message even if the extension displays a warning. If disableSend is set as true, when the user clicks the send button it becomes disabled while the extension is loading and validating the mail. There are a number of options available to the extension:

  • If it determines the mail is OK to send it can allow it to be sent without any further action from the user.
  • If it wants to display a warning to the user but still allow them to send the mail it can display a UI and re-enable the send button.
  • If it wants to block the user from sending the mail it can display a UI and leave the send button disabled.
  • In case the external application fails to load, the ‘Send’ button will be automatically re-enabled and a message will be displayed to the user warning them that there is risk associated with sending the mail because the extension to which validates mails cannot be loaded.

 

Required Properties for a Before On Send

  • {string} id The id for the custom name picker.
  • {string} url The widget’s url, when the Send button is clicked, the URL is opened in a hidden iframe.

 

Example Before On Send

{
"name": "Hook Before Send Sample",
"title": "Hook Before Send Sample",
"description": "Sample that shows how to check for a credit card number in mail being sent",
"extensions": [
{
"type": "com.ibm.verse.ext.beforeOnSend",
"name": "Hook Before Send Extension",
"title": "Hook Before Send Extension",
"url": "${extensionPath}/hook-before-send/index.html"
}
],
"services": [
"Verse"
]
}

   

Live Text (com.ibm.verse.ext.liveText)

The Live Text extension point recognizes defined patterns of data in email, and displays the information with an underline. Clicking the live text displays a menu of custom actions; for example, to open a web application or start a chat. The pattern and the corresponding actions are defined in an extension that is added to Verse.

  Note: For a tutorial on creating Live Text extensions in Verse, see Live Text Extension Tutorial. For instructions on exporting Live Text widgets from Notes so you can import them into Verse, see Exporting a Live Text Widget from IBM Notes

 

Required Properties for Extensions

  • {string} text The text for the Live Text action.
  • {string} href The Live Text link location. Use ${groupNumber} to define a variable in the href. The groupNumber is the group number of regular expression defined in recognizer. When execute a Live Text action, the ${groupNumber} will be replaced with text recognized by the groupNumber group.
  • {string} recognizer A regular expression in string form, not a regex literal, to recognize the specified text pattern as Live Text.

 

Optional Properties for Extensions

  • {string} alt Alt text for Live Text action.
  • {string} location This property specifies where to open the Live Text extension. The acceptable values can be window or tab.
    • window - The Live Text extension will be opened in the new window. We can use renderParams to specify the new window’s size. If renderParams is not provided, a default renderParams will be used.
    • tab - The Live Text extension will be opened in the new tab.
  • {object} renderParams This property specifies the window size when the extension is open in a new window. The renderParams property contains width and height properties, which are used to specify the new window’s width/height accordingly. This property is only valid if the location’s value is window.

 

Example Live Text extension

{
"name": "Live Text Widget Sample application",
"title": "Live Text Widget Sample",
"description": "The sample shows how to contribute a live text extension in Verse",
"extensions": [
{
"name": "Live Text Widget Sample extension",
"type": "com.ibm.verse.ext.liveText",
"payload": {
"text": "Live Text Widget Action",
"href": "${extensionPath}/${1}/sample1.html?tel=${2}",
"recognizer": "Path:([a-z].*), Tel:([0-9]{8}).*",
"location": "window",
"renderParams": {
"width": "800",
"height": "600"
}
}
}
],
"payload": {},
"services": [
"Verse"
]
}

The ${extensionPath} in above example is only a path var of this repository. You need to use absolute path in their own extensions if their extension page is not in this repository.

Registering an Application in IBM Verse

For development purposes you can use the IBM Verse Developer Extension for Google Chrome to register an application. There is a tutorial to get you started.  

Your Application

You will need to provide Verse with the URL to your web application. Once an extension is clicked in the Verse UI, the URL will be loaded in a new window. If cross-document messaging is configured, the initial web page can use JavaScript to listen for a window message event containing a context object after it loads. This object has information from Verse for your extension, as specified in the applications.json file.

When using the Chrome extension, you will need to add the URL of your application and the extension(s) to the applications.json file. The Chrome extension will use the extension definitions from this file and register them with Verse.

 

File structure of applications.json

The applications.json file contains a list of Application definitions in JSON format

[
{
"name": "application one",
...
},
{
"name": "application two",
...
}
]

 

Here are three different samples of valid applications.json:

 

Application Properties

An application definition must contain the following properties:

  • name The name of your application. This must be unique.
  • title The title of your application.
  • description The description of your application.
  • extensions An array of of extension definitions. See below for the properties of this object.
  • services Describes which services the extension is deployed to. "Verse" is the only supported value.

 

Extension Properties

For extension properties, please refer to Verse Extension Points for details.

Deploy application on Verse on-Cloud

To add an application to Verse on-Cloud, you need to register it using the IBM App Registry. You can refer to this guide Managing extensions for Verse for details.

Deploy application on Verse on-Premise

To add an application to Verse on-Premise, Verse supports two approaches to deploy your applications/extensions to end users:

  • Deploying extensions using the built-in endpoint
  • Deploying extensions using a custom endpoint

Deploying extensions using the built-in endpoint

Verse On-Premises implemented a built-in endpoint to serve the application’s JSON data from a local file or an HTTP hosted file. If storing the applications JSON data as a static file works for you, this is the way to go.

Two data providers are implemented in the built-in endpoint:

  • Local file data provider: Serves the applications JSON data from a local file on the Domino server. This allows you to deploy extensions without dependency on another server. The path of the file can be specified using a notes.ini parameter VOP_Extensibility_Applications_Json_FilePath.
  • HTTP data provider: Serves the applications JSON data from an HTTP hosted file. This allows you to deploy applications.json to a centralized HTTP server. The HTTP URL of the file can be specified using notes.ini parameter VOP_Extensibility_Applications_Json_URL.

The notes.ini parameter VOP_Extensibility_Data_Provider_Name controls which data provider to use, either localFileProvider or httpDataProvider. By default, if none is specified, localFileProvider will be used. In either case, the data provider will periodically check the source applications.json file for updates, so you don’t have to restart the server after a new version of applications.json is deployed.

To use the local file data provider:

  1. Make sure notes.ini parameter VOP_Extensibility_Data_Provider_Name is either clear or set to localFileProvider.
  2. Deploy applications.json to the Domino server.
  3. Make sure notes.ini parameter VOP_Extensibility_Applications_Json_FilePath is set to the file path of applications.json. For example:
VOP_Extensibility_Applications_Json_FilePath=D:\data\applications.json

To use the HTTP data provider:

  1. Make sure notes.ini parameter VOP_Extensibility_Data_Provider_Name is set to httpDataProvider.
VOP_Extensibility_Data_Provider_Name=httpDataProvider
  1. Deploy applications.json to the HTTP server.
  2. Make sure notes.ini parameter VOP_Extensibility_Applications_Json_URL is set to the HTTP URL of applications.json. For example:
VOP_Extensibility_Applications_Json_URL=https://files.renovations.com/vop/applications.json

Deploying extensions using a custom endpoint

If you would like to serve the applications.json data dynamically using code, you can specify a custom endpoint (which you implement) to do so. The HTTP URL of the custom endpoint can be specified using notes.ini parameter VOP_Extensibility_Endpoint_URL. For example:

VOP_Extensibility_Endpoint_URL=https://rest.renovations.com/vop/appregistry/services/Verse/applications

The custom endpoint MUST return the same response format as IBM Connections Appregistry API (see Retrieving a list of all extensions), otherwise, Verse will not be able to correctly parse the response and get the extensions. You can see the response format below. In the items, it contains all of your registered applications/extensions. Format for items list

The following table lists related notes.ini parameters that you can use based on your specific needs. You can find each parameter’s description, allowed value, and its default value in the table.

Parameter name Description Allowed value Default value
VOP_Extensibility_Endpoint_URL HTTP URL of the custom endpoint. HTTP URL (must be https)  
VOP_Extensibility_Data_Provider_Name Which data provider to use when the built-in endpoint is being used. localFileProvider or httpDataProvider localFileProvider
VOP_Extensibility_Applications_Json_FilePath File path of applications.json when LocalFileDataProvider is being used. Absolution file path {domino_data_directory}/vop/applications.json
VOP_Extensibility_Applications_Json_URL HTTP URL of applications.json when httpDataProvider is being used. HTTP URL (http or https)  

Sending and Receiving Data

Verse supports both URL query string parameters and/or cross-document messaging to communicate with your application. Both methods are described below.

 

Passing data in a URL

Your application can receive data from Verse through URL query string parameters, which are added to the URL specified in the applications.json file. Valid parameters are described in the Verse API Data section.

For example, to send the name of a user from a business card extension to your application, specify the following URL in the applications.json file: https://<your-domain-here>/extension.html?username=<profile.name>.profile.name is a variable that contains the user’s name.

In your application, you retrieve the URL query string parameters as usual.

 

Passing data through cross-document messaging

If your web application cannot support receiving data from a URL request, you can use cross-document messaging instead. To use this method, you must add the features property to the manifest with the value of ["core"] so that your web application can communicate with Verse.

In your application code, you must send a "com.ibm.verse.application.loaded" message back to the Verse window, so that Verse knows your web application is ready to receive data. If you have a reference to the Verse window, you can do this at the beginning of your code; otherwise wait for the message "com.ibm.verse.ping.application.loaded" because the source of this message will be the Verse window.

To handle messages from Verse, your web application needs to register an event listener by using:

window.addEventListener("message", function(event) {
// handle message event code
});

 

See here for the complete code source of a sample application that demonstrates the concepts described in this section. Please be aware that this example lacks certain security implementations for simplicity. To make it more secure for your own purpose, please refer to the Security section, which includes suggested security implementations when using cross-document messaging.

Verse API Data

Verse is able to send data to your application using what’s known as a context object. It is passed in the message event object of the window.postMessage function. This section shows the structure of the different context objects that are sent by Verse.

The information contained in the context object depends on the action extension used. For example, adding a mailRead action extension sends information relating to the selected mail: title, subject, body, etc. Adding a business card action extension sends the person’s name, email, phone, etc.

 

Parsing the Verse API Data

The message event received by your application contains an object called data, which has an object called verseApiData. You will need to check that the actionId property of the verseApiData object matches the extension id in your application.json file. This will ensure that you only run your code for the correct message events.

 

For example:

window.addEventListener("message", function(event) {
if (event.data.verseApiData.actionId === "com.ibm.verse.action.sample.person") {
var verseData = event.data.verseApiData.context;
}
}

In the code example above, you can see that the information that you need from Verse is stored in the context property, which you can check with the if statement. The value of the verseData variable depends on which extension is used.

In the sections below, the structure of each of the different context objects is outlined.

 

Widget Extensions

  • mail.compose: This appears when composing a new mail under the more actions button.
  • mail.read: This appears when viewing an existing mail under the more actions button.
  • person: This appears on the back of the business card.

 

Mail Compose

{
"body": "",
"contextId": "",
"id": "",
"recipientCC": [
{
"displayName": "",
"emailAddress": ""
}
],
"recipientTo": [
{
"displayName": "",
"emailAddress": ""
}
],
"subject": ""
}

 

Mail Read

{
"body": "",
"contextId": "",
"id": "",
"recipientCC": [
{
"displayName": "",
"emailAddress": ""
}
],
"recipientTo": [
{
"displayName": "",
"emailAddress": ""
}
],
"sender": {
"displayName": "",
"emailAddress": ""
},
"subject": "",
"timeSent": ""
}

 

Person

{
"currentUser": {
"company": "",
"displayName": "",
"fax": "",
"id": "",
"jobTitle": "",
"mobilePhone": "",
"name": {
"displayName": "",
"displayType": "",
"familyName": "",
"formatted": "",
"givenName": "",
"honorificPrefix": "",
"honorificSuffix": "",
"middleName": ""
},
"network": "",
"photo": "",
"photoUrl": "",
"primaryAddress": "",
"primaryEmail": "",
"primaryPhone": "",
"status": "",
"tags": "",
"website": ""
},
"profile": {
"company": "",
"displayName": "",
"fax": "",
"id": "",
"jobTitle": "",
"mobilePhone": "",
"name": {
"displayName": "",
"displaytype": "",
"familyName": "",
"formatted": "",
"givenName": "",
"honorificPrefix": "",
"honorificSuffix": "",
"middleName": ""
},
"network": "",
"orgId": "",
"photo": "",
"photoUrl": "",
"primaryAddress": "",
"primaryEmail": "",
"primaryPhone": "",
"status": "",
"tags": "",
"website": ""
}
}

Editing The Manifest

If the URL that you use to access Verse is specific to your company, you need to add it to the manifest.json file. You can follow our tutorial on how to update manifest.json.

Security

As your website is using cross-document messaging to communicate with Verse, it can be vulnerable to cross-site scripting attack unless certain security implementations are followed carefully. Here are three tips to make your application less vulnerable.

 

When receiving message, always verify origin of the message

In this sample HTML page, we did not verify origin of the message as we need to make sure the page works with any domain for demoing purpose. However, in a production environment, immediately after the line:

window.addEventListener("message", function(event) {

 

you should add the following code to check the origin of the message and prevent the rest of the JavaScript code from executing if the message origin does not match your Verse domain:

if (event.origin !== "<your-Verse-domain-here>"){
return;
}

 

When sending message, always specify targetOrigin

targetOrigin provides control over where messages are sent. Your application needs to specify targetOrigin so that it will not end up sending sensitive information to malicious site.

In this sample HTML page, when posting message from the sample page back to Verse, we are specifying the targetOrigin to be the origin of the previous event we received (event.origin), instead of using a wild card *:

event.source.postMessage(loaded_message, event.origin);

 

If you have verified origin of the message by implementing the suggestion in the previous tip, you can be sure that event.origin here would be your Verse domain.

 

Always validate the messages being passed

This includes trying to use innerText or textContent instead of innerHTML when inserting data value into the DOM so as to avoid malicious code being inserted and executed.

It is the responsibility of the extension developer to ensure data received is treated appropriately. For example, with the HTML sample page, if it used insertAdjacentHTML instead of innerText to display the stringified JSON data from the user’s side and a mail subject contained the following line (either in the Mail Compose View or Mail Read View) then when the extension is triggered, a button would be added onto the application’s HTML page, which when clicked, will show an alert:

</div><button onclick='alert()'>Click me!</button><div>

This is a proof of concept to show how malicious users can take advantage of this vulnerability to execute their own script.

To learn more about cross-site scripting attack, please refer to the OWASP site.

On the extension side, Google Chrome has also given some suggestion on how to make your Chrome extension more secure. Please refer to their documentation on Content Security Policy and Cross-Origin XHR for details.

Troubleshooting

This section describes some common issues you might experience and provides information on how to debug your application.

 

The Chrome Developer Extension will not load

If you are experiencing problems loading the Chrome Developer Extension as an unpacked extension, this is most likely an issue with the manifest.json or applications.json files. When you edit these files, ensure that they are well-formed with no trailing commas, no missing quotation marks, no syntax errors, etc.

 

The Chrome Developer Extension loads, but your extensions do not appear in Verse

If your extensions are not appearing in the Verse UI, make sure that you have specified the correct path and object properties in the applications.json. Also ensure that you have added the URL that you use to access Verse to the manifest file. See here to read more on editing the manifest.

 

Debugging your application

Your application opens in a new window but is not working as expected, or does not appear to have received any data from Verse.

This might be an issue with the applications.json file. If you are using URL query string parameters, verify that the variables you added to your URL are valid and correspond to properties in the Verse API data section. If you are using cross-document messaging, verify that you have specified the value ["core"] for the payload.features property.

If you are still having problems, you will need to debug your application code using the browser developer tools. Since Verse opens your application in a new window that immediately executes your code, you will not have enough time to open the developer tools and set break points.

The simplest solution to this is to add an alert(); followed by a debugger; statement.

When the new window opens and your application code starts to execute, the alert will appear and will pause the execution of your code until the alert is dismissed. Before dismissing the alert, open the developer tools. Now dismiss the alert and the the code will pause at your debugger statement.

Inspect the message event listeners and make sure that they are receiving the correct data from Verse. Verify that you are sending the com.ibm.verse.application.loaded message to the Verse window to indicate that your application is ready to receive data.

See here for more information on communicating with the Verse window.