Share this page

# External actions

You can create external actions and embed them in the UI. External actions can launch external websites or applications that interact with OpenText Software Delivery Management.

Note: External actions are available as a technical preview.

In this topic:

## External action types

External actions can be created to add the following elements to the application: custom toolbar buttons sidebar plugins, and scripted widgets.

External action type | Description
--- | ---
Custom toolbar button | Adds a new button to toolbars of specified entities. When clicked, the button can interact with the selected items in a prescribed way, or open an external website or application.
Sidebar plugin | Adds a new sidebar interface for specified entities. The sidebar plugin consists of a custom web page that is embedded in the sidebar pane.
Scripted widget | Adds a scripted widget to the dashboard widget gallery. These widgets can be added to dashboards to visualize data using custom logic and JavaScript.

The current topic provides information that applies to all types of external actions. For additional guidelines on creating sidebar plugins, see Sidebar plugins.

Note: Work with external actions requires space admin permissions. For details, see Roles and permissions.

Back to top

## External action components

An external action consists of two parts: a JSON object and the action's code.

JSON object

The action's configuration is defined by a JSON object. The object describes the action's properties, such as its title, and the entity types that the external action applies to. Some properties are relevant to all types of external actions, and others are specific to certain types.

For details, see JSON structure.

External action code

The code is the external action's implementation.

- You can upload the code to OpenText Software Delivery Management, or host it on an external server.

- If you host the code on an external server, you must establish trust between the OpenText Software Delivery Management server and the external server. For details, see Use CORS for external actions.

- To interact with data from OpenText Software Delivery Management, the code can include REST API requests. For details, see REST API.

Back to top

## Create an external action

You can define external actions in the following ways:

- Upload a zip bundle that includes a JSON file and any accompanying code files.
- Add a JSON object in the External action editor in the UI, and reference remote code files.

Tip: Click Load Demo to load JSON code with examples of various configuration options for the external actions.

Upload a zip bundle

The zipped bundle must include the following files:

- A JSON file named action-configuration. The file must include a single external action configuration.

  The JSON file must be at the top level of the zip.

- Code files implementing the external action. The executable file should be referenced from the url property in the JSON object.

To upload a zip bundle:

1. As a Shared Space admin, select Settings > Management > External action editor.

2. In the External action editor, click the Upload Bundle button .

   The Upload Bundle for Action dialog box opens.

3. In the Upload Purpose field, select Upload New Action.
4. Click the Select bundle button .

5. Locate the zip file, and click OK.

   The configuration of the new action is added to the existing objects in the external action editor.

Define an external action in the editor

Add an external action by creating a JSON object directly in the External action editor.

To define an external action in the editor:

1. As a Shared Space admin, select Settings > Management > External action editor.

2. Add a JSON external action object.

3. Click Save.

Back to top

## Supported events

You can send the following OpenText Software Delivery Management events from the web application to the action.

Event | Description
--- | ---
`octane_refresh_entity` | Instruction to refresh specified items after they have been updated in the external application.
`octane_display_entity` | Instruction to display details of a specified item.
`octane_entity_was_added` | Notification that a new item was created. The new item is displayed where relevant, the same as it would had it been created inside OpenText Software Delivery Management. For example, when adding a new defect, if the defects grid is displayed, the defect is displayed at the top of the grid.
`octane_refresh_list` | Instruction to refresh the full grid after an update was made in the external application.
`octane_select_entity` | Instruction to select specified entities in the grid.
`octane_set_dialog_title` | If the external action opens a dialog box, use this event to set the dialog box's title.
`octane_close_dialog` | If the external action opens a dialog box, use this event to close the dialog box.
`octane_read_settings` | Queries for the current user's settings for the application or a specified module. The results are returned in JSON format.
`octane_update_settings` | Adds a new value to the settings. The value is stored in the "text" key.
`octane_report_error` | Instruction to add an entry to its errors log.
`octane_read_widget_configuration` | For scripted widgets only: Request the current configuration for a specific widget by panel_id. OpenText Software Delivery Management receives the panel_id from the external script and responds by sending the widget's configuration via the `octane_widget_configuration` event. The message should have the following structure: `data: { panel_id: <panel_id from url> }`
`octane_widget_configuration` | For scripted widgets only: Provides the configuration to the external script. When subscribed to the read event in OpenText Software Delivery Management, it returns the configuration from the user's settings. On first use, the received configuration object is empty. Listen for this event and get the configuration from OpenText Software Delivery Management via `data.config`.
`octane_update_widget_configuration` | For scripted widgets only: Updates the configuration in user settings. Receives the new configuration from the external script and updates it. This update event is triggered by the external action whenever a change occurs, and it's called each time the configuration changes. The message should have the following structure: `data: { panel_id: <panel_id from url>, config: <external_widget_config object> }`

Implementation notes

- The code should be implemented in the target web application.
- For actions opened in a new browser tab, post messages using `window.opener`.
- For actions embedded inside a dialog box, post messages using `window.parent`.
- If the code fails on "opener undefined", check that the action is configured with `"events": true`.
- If a refresh event or a message is sent for an entity that is currently being edited by the user and has changes unsaved to the server, the UI will not refresh to prevent data loss.

Code examples

The following examples assume that `params` holds parameters that were sent to the external application using the `url` parameter.

Event | Example
--- | ---
`octane_set_dialog_title` | Copy code
    var message = {
        event_name: 'octane_set_dialog_title',
        shared_space: '1004',
        workspace: '1006',
        data: {
            dialog_id: params.dialog_id,
            title: 'Our custom dialog title',
        },
    };
    window.parent.postMessage(message, '*');
`octane_close_dialog` | Copy code
    var message = {
        event_name: 'octane_close_dialog',
        shared_space: '1004',
        workspace: '1006',
        data: {
            dialog_id: params.dialog_id,
            refresh: true,
        },
    };
    window.parent.postMessage(message, '*');
Set `refresh: true` in the message to refresh the displayed view. This refreshes the grid or the details view, depending on the view from which the action was triggered.
`octane_refresh_entity` | Copy code
    var message = {
        event_name: 'octane_refresh_entity',
        shared_space: '1004',
        workspace: '1006',
        data: {
            entity_type: 'work_item',
            entity_ids: ['1003', '4005'],
        },
    };
    window.opener.postMessage(message, '*');
`octane_display_entity` | Copy code
    {
        event_name: 'octane_display_entity',
        shared_space: '1004',
        workspace: '1006',
        data: {
            entity_type: 'work_item',
            entity_id: '1050',
        },
    }
`octane_entity_was_added` | Copy code
    {
        event_name: 'octane_entity_was_added',
        shared_space: '1004',
        workspace: '1006',
        data: {
            entity_type: 'defect',
            entity_id: '1050',
        },
    }

Back to top

## Icons

Choose an icon from the list below to use for the custom button or sidebar.

Tip: To view in full detail, click to zoom in, then right-click the image and open in a new tab.

Back to top

## Verify user identity

Applications that interact with OpenText Software Delivery Management can verify if the user that invoked an external action is a user currently signed in to OpenText Software Delivery Management.

External actions can do the following:

- Verify user identity with a token

- Verify user identity using CORS authentication

Verify user identity with a token

You can configure an external action to send the `{user_identity_token}` to a target application as a query parameter. The target application can then use the token information to verify the identity of an OpenText Software Delivery Management user that invoked an external action.

The `{user_identity_token}` is a JSON Web Token (JWT).

When using the token information, an external action does not need to send authentication requests to confirm the user identity.

Note: For GDPR compliance, when using the `{user_identity_token}`, an OpenText Software Delivery Management user must agree to share their identity information.

The `{user_identity_token}` contains the following information:

Property | Details
--- | ---
`name` | Username of the OpenText Software Delivery Management user.
`email` | Email of the OpenText Software Delivery Management user.
`iat` | Unix time, in seconds, that represents the token issue date.
`exp` | Unix time, in seconds, that represents the token expiration date.

To verify user identity with the token:

1. If you are verifying the token validity from an external action's web application, and not from the server, allow OpenText Software Delivery Management to support CORS by setting the CORS_ENABLED parameter to true. This lets an external action make requests to OpenText Software Delivery Management from the hosted iFrame.

   Skip this step when verifying the token validity from the server.

2. Configure an external action to support user identity tokens by adding the `{user_identity_token}` URL token to the action's `url` property.

   Following is a sample `url` configuration that uses the `user_identity_token` property:

   Example: `"url": "{bundle_url}/my_folder/index.html?entity_ids={entity_ids}&entity_type={entity_type}&shared_space={shared_space}&workspace={workspace}&user_login={user_login}&email={user_email}&octane_url={octane_url}&dialog_id={dialog_id}&user_identity_token={user_identity_token}"`

   When an OpenText Software Delivery Management user clicks an action button, or a tab that displays the external action in an iFrame, a user identity token is generated and added to the external action invocation URL.

3. Confirm the identity of an OpenText Software Delivery Management user:

   1. Extract `user_identity_token` from the request.
   2. Parse the `user_identity_token` and decode the token information using the Base64 decoder or any other third-party library that fits your programming paradigm.
   3. Verify the token expiration date.

   4. Verify the `user_identity_token` validity with the help of a public key. You can retrieve the key using the following API request: `https://<octane.example.com>/api/jwt/key`.

      Technical preview: This API is technical preview. When calling it, use the ALM-OCTANE-TECH-PREVIEW header.

      The RSA public key is returned as a Base64-encoded string.

   5. Using the public key, verify the token signature.

      Depending on the library you are using to verify the token signature, you may need to convert the key to the PEM format by adding the header and footer strings. Below is an example of JavaScript for the key PEM format.

      Example:

      `const {key: publicKey} = await response.json();`

      `const publicKeyInPEMFormat = '-----BEGIN PUBLIC KEY-----' + publicKey + '-----END PUBLIC KEY-----';`

Verify user identity using CORS authentication

Interacting applications can verify a user's identity using the CORS request.

To verify the user identity using the CORS request:

1. Allow support for CORS by setting the CORS_ENABLED parameter to true.
2. Ensure the CORS_AUTH_ALLOW_ORIGIN parameter lists the external action server base URL.

3. Ensure the SAME_SITE_COOKIE_ATTRIBUTE parameter controlling cookies is set to none.

   For details, see Configuration parameters.

These settings allow an external action to send requests from the external action's web application to the OpenText Software Delivery Management's server using the current authentication context, established when the user signed in to OpenText Software Delivery Management.

To get the details of a currently signed-in user, such as a user ID and email, the external action can call https://octane.example.com/api/current_user.

Example: `{"id": "<userid>", "email": "<user@email.com>", "name": "<username>" //user name in OpenText Software Delivery Management}`

Back to top

## Use CORS for external actions

If your external actions are hosted on a domain other than OpenText Software Delivery Management, you can establish trust by either using an API key in the code, or using the CORS mechanism.

This section discusses using the CORS mechanism for external actions.

The CORS mechanism for external actions involves the following:

- Setting CORS configuration parameters
- Sending an anti-CSRF cookie in requests

To enable CORS actions:

1. Make sure the following CORS parameters are enabled and configured: CORS_ENABLED, CORS_ALLOW_ORIGIN, CORS_AUTH_ALLOW_ORIGIN, CORS_MAX_AGE

2. Set the following site parameter:

   Parameter | Value
   --- | ---
   SAME_SITE_COOKIE_ATTRIBUTE | None

   For details, see Configuration parameters.

To send an XSRF cookie in requests:

To prevent non-authorized servers from accessing the OpenText Software Delivery Management server, requests from external servers need to include an XSRF header that sends a unique cookie.

Following is a sample code snippet for an XSRF header:

Copy code

    const xsrf = new URL(document.location.href).searchParams.get('xsrf_token')

    await fetch(url, {
        headers: {
            "XSRF-HEADER": xsrf,
            "content-type": "application/json",
        },
        method: "PUT",
        ...
    });

Back to top

## Host external actions

As an alternative to storing external action code on an external server and establishing trust with OpenText Software Delivery Management, you can upload the external action code to OpenText Software Delivery Management.

You can upload all the external actions in the same zip file, or upload each external action in a separate file.

With bundled files, the different external actions can also use shared code. For example, if you have external actions `foo` and `bar` that reference shared code `common`, structure the folders as follows:

Prerequisites

- Make sure that the parameter SUPPORT_EXTERNAL_ENTITY_ACTIONS_BUNDLE is enabled.
- Configure the other external action parameters as required: EXTERNAL_ENTITY_ACTIONS_BUNDLE_MAX_SIZE, EXTERNAL_ENTITY_ACTIONS_FILE_EXTENSION_WHITE_LIST

For details, see Configuration parameters.

To upload external actions:

1. Define the action in the external action editor, using the JSON syntax. For details, see Create an external action.

2. Click the Upload Bundle button .

   In the Select Action dropdown list, select the name of the action whose code you want to upload, or select Common to upload a bundled file.

   Note: To replace a bundled zip that contains multiple actions, select Common.

3. Locate the zip file and upload it.

   An internal guid is created for the action, and the guid is added to the external action definition in the JSON.

1. In the external action editor, update the `"url"` property to point to the uploaded file, as follows: `"url": {bundle_url}/foo.html`

   `{bundle_url}` is a token denoting OpenText Software Delivery Management's server address.

Back to top

## REST API for external actions

The following examples demonstrate GET and PUT scripts for reading and updating external actions.

Get external actions

Copy code

    GET https://alm-octane.example.com/api/shared_spaces/1001/external-entity-actions
    HEADERS:
     - ALM-OCTANE-TECH-PREVIEW: true

Update external actions

Copy code

    const entity = {
        fieldName: fieldValue,
    };

    const xsrf = new URL(document.location.href).searchParams.get('xsrf_token')

    fetch(
        '/api/shared_spaces/' +
        sharedSpaceId +
        '/workspaces/' +
        workspaceId +
        '/work_items/' +
        entityId,
        {
            headers: {
                'content-type': 'application/json',
                'XSRF-HEADER': xsrf,
            },
            body: JSON.stringify(entityData) ,
            method: 'PUT',
            credentials: 'include',
        }
    );

Back to top

See also:

- Sidebar plugins

- JSON structure

https://admhelp.microfocus.com Software Delivery Management 8942
Tips to improve your search results... OpenText™ Software Delivery Management Help Center OpenText™ Software Delivery Management Help 26.1 All View Local Help Center View Online Help Center Version: