Defining an App

Developers can create 2 main types of apps for Percolate:

An App with a UI Extension - these apps will display a UI Extension within Percolate and visibly integrate with the Percolate workflow. They may or may not access Percolate data.

An App without a UI Extension - these apps do not display a UI within Percolate but require access to Percolate data.

In both cases, the starting point for creating an app is the App manifest.

Defining your App with an App Manifest

The App manifest is a JSON file describing the characteristics and the requirements of an app. It is uploaded to register an App to a Percolate account.

{
  "name": "Crostini",
  "version": "1.1.0",
  "description": "A demo for Percolate Developer Platform (PDP)",
  "environment": "production",
  "developer": "Percolate, Inc.",
  "developer_email": "[email protected]",
  "support_website": "https://example.com",
  "logo": "https://prclt-crostini.herokuapp.com/logo.svg",
  "capabilities": ["brief:read", "brief:create", "brief:edit", "brief:delete"],
  "lifecycle": {
    "install": "https://prclt-crostini.herokuapp.com/install",
    "uninstall": "https://prclt-crostini.herokuapp.com/uninstall"
  },
  "extensions": [
    {
      "location": "campaign_tab",
      "label": "Crostini",
      "url": "https://prclt-crostini.herokuapp.com/campaign"
    },
    {
      "location": "settings",
      "label": "Crostini",
      "url": "https://prclt-crostini.herokuapp.com/settings"
    }
  ]
}
PropertyDescription
descriptionA short description of the app functionality.
requirements (optional)The technical text listing what the app requires to function properly. For ex: "Requires admin account permissions to log into the app"
release_notes (optional)The description of the reason for uploading the new manifest. A full changelog can be compiled from the release notes of all versions of an application.
logoA URL pointing to either an image or SVG. The logo should preferably be squared, 128 by 128 pixels with a transparent background.
developerThe developer’s name.
developer_emailThe developer’s email.
support_websiteThe website URL intended for support.
environmentMust be set to “production” for apps intending to be installed to multiple tenants, otherwise “development” if it will only be installed in a single tenant.
versionThe semantic version of the app.
capabilities (optional)List of Percolate capabilities to give the app access to specific Percolate endpoints and data. Learn how to define capabilities with this page.
extensions (optional)See defining UI Extensions section below.
lifecycle (optional)See defining lifecycle callbacks section below.

Defining UI Extensions

A UI Extension JSON Object defines where, what, and how an App displays its UI within Percolate.

PropertyDescription
locationOne of the 7 location ids:

top_nav - shows an icon in the global nav dropdown linking to a fullpage UI
campaign_tab - shows a tab on the Campaign Page
post_tab - shows a tab on the Content Page
asset_tab - show a tab on the Asset Page
request_tab - shows a tab on the Request Page
task_tab - shows a tab on the Task Page
settings - show a tab on the Installed App Page
urlThe URL for the chosen location. Must use HTTPS.
labelThe name of the extension to be displayed.
logo (optional)A URL pointing to either an image or SVG. The logo should preferably be squared, 128 by 128 pixels with a transparent background.

Understanding UI Extension Context

UI Extensions are rendered within an IFRAME in Percolate. To provide contextual data, a JSON Web Token (JWT) assigned to the jwt query param is appended to the extension’s URL.

Example:

https://prclt-crostini.herokuapp.com/app/campaign.html?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6.MjM0NTY3ODkwIiwibm.XbPfbIHMI6arZ3Y922BhjWgQzWXcXNr

Our JWT is signed using the App Secret with HMAC SHA256 algorithm (HS256).

Once decoded and verified, the payload, here called UI Extension Context, has the following properties ("claims" in JWT parlance):

{
  "aud": "prclt-crostini.herokuapp.com",
  "exp": 1572014710,
  "iat": 1572014650,
  "iss": "percolate.com",
  "jti": "e7d52da8-f435-41e9-9d35-c24db67e1d2c",
  "sub": "user:123",
  "app_id": "app:123456789_123456789",
  "location": "campaign_tab",
  "object_id": "campaign:123",
  "object_scope_id": "license:123",
  "tenant_id": "tenant:1",
  "user_id": "user:123"
}

Standard Properties

Also known as reserved claims in the JWT standard.

PropertyDescription
audAudience, the recipient’s domain name the JWT is intended for.
expExpiration time, after which the JWT must not be accepted for processing. The value is set at exactly 1 minute after the "issued at" (iat) time and formatted as a NumericDate.
iatIssued at, the time at which the JWT was issued. The value is formatted as a NumericDate.
issIssuer of the token. Always set to “percolate.com”.
jtiJWT ID, the case sensitive unique identifier of the token.
subSubject, the user accessing the UI extension that caused the JWT to be sent.

Non-standard Properties

Also known as custom claims.

PropertyDescription
app_idThe Percolate app id.
locationThe id of the current UI location. One of the 7 location ids:
top_nav
campaign_tab
post_tab
asset_tab
request_tab
task_tab
settings
object_idThe Percolate id of the resource being viewed based on the location.

Undefined for top_nav and settings locations.
object_scope_idThe owner scope of the resource being viewed based on the location.

Undefined for top_nav and settings locations.
user_idThe id of the current session user.
tenant_idThe id of the tenant/account the user is currently logged into.

Defining lifecycle callbacks

Developers can optionally define callbacks for events happening throughout the life of an installation. When a lifecycle event is fired, a POST request will be made to the appropriate URL registered for the event.

Six events can be registered to a callback under the manifest’s lifecycle field. Each URL must use HTTPS to ensure data is sent securely.

Apps can verify that the request came from Percolate using the X-Perc-App-Secret request header, which is sent with all lifecycle requests. Its value should be the same as the app secret that encodes the UI extension’s JWTs.

"lifecycle": {
  "install": "https://prclt-crostini.herokuapp.com/install",
  "uninstall": "https://prclt-crostini.herokuapp.com/uninstall",
  "enable": "https://prclt-crostini.herokuapp.com/enable",
  "disable": "https://prclt-crostini.herokuapp.com/disable",
  "update": "https://prclt-crostini.herokuapp.com/update",
  "upgrade": "https://prclt-crostini.herokuapp.com/upgrade"
}

Install

install is required for apps needing access to Percolate’s data as it provides the access_token needed to authorize requests.

{
  "app_installation_id": "app_installation:12345",
  "metadata_source": "notset",
  "tenant_id": "tenant:123",
  "access_token": "1QJiVA_PM_I_t3bqr0xEWsvAIksjg...q8YY8yw_7o7OS88",
  "machine_user_id": "user:123",
  "manifest_version": "1.0.0",
  "access_scopes": [
    {
      "scope_id": "license:100",
      "is_hierarchical": true
    }   
  ]
}
PropertyDescription
tenant_idThe id of the tenant/account the app is installed under.
access_tokenAn OAuth 2.0 compliant Bearer token. See here for a usage example. It does not expire.
machine_user_idThe bot user id used by the app to access data from Percolate.
manifest_versionThe semantic version of the installed app as defined in the manifest.
access_scopesThe list of access_scope JSON objects defining which scopes to authorize data access.

scope_id - the scope id within a tenant where data access is granted.

is_hierarchical - if true, child scopes under the above scope_id will be granted data access.
app_installation_idThe app_installation_id for the given installation. Currently used for retrieving uix_visibility criteria.
metadata_sourceEnum that is initially set to notset - can also be seismic and percolate. Determines if the installation will have Seismic as the metadata source or Percolate i.e. metadata field data will come from Seismic or Percolate for mappings created in the future.

Enable

This callback is triggered when an installed app is enabled / activated. This means that Percolate will display the UI extensions as defined in the manifest under the appropriate conditions.

{
  "tenant_id": "tenant:123"
}
PropertyDescription
tenant_idThe id of the tenant/account the app is installed under.

Disable

This callback is triggered when an installed app is disabled / made inactive. This means that the UI extensions that the app defines will become hidden.

{
  "tenant_id": "tenant:123"
}
PropertyDescription
tenant_idThe id of the tenant/account the app is installed under.

Update

This callback is triggered when the data access scopes of an installed app have changed.

{
  "tenant_id": "tenant:123",
  "access_scopes": [
    {
      "scope_id": "license:100",
      "is_hierarchical": true
    },
    {
      "scope_id": "license:200",
      "is_hierarchical": false
    }   
  ]
}
PropertyDescription
tenant_idThe id of the tenant/account the app is installed under.
access_scopesThe list of access_scope JSON objects defining which scopes to authorize data access.

scope_id - the scope id within a tenant where data access is granted.

is_hierarchical - if true, scopes nested under the above scope_id will be granted data access.

Upgrade

This callback is triggered when an installed app is upgraded.

{
  "tenant_id": "tenant:123",
  "manifest_version": "2.0.0",
}
PropertyDescription
tenant_idThe id of the tenant/account the app is installed under.
manifest_versionThe new version of the manifest the installation is now using.

Uninstall

This callback is triggered when an installed app is uninstalled. At that time, the access_token provided by the install callback becomes permanently invalid. A new one will be reissued once the app is reinstalled.

{
  "tenant_id": "tenant:123"
}
PropertyDescription
tenant_idThe id of the tenant/account the app was installed under.

Registering an App

A a new custom app must be registered in order to be made available for installation. To register an app:

  1. Go to Settings > Developer > App registration and then click the + New app button in the upper right corner.
  1. Upload your app's manifest JSON document.
12791279
  1. The new app will now display on the App registration page.

The following actions can be taken on the app:

Upload new version: Uploading a new manifest will update the definition of an existing app. A new version of the app is created each time a new manifest is uploaded.

📘

App installations pointing to an old version will need to be upgraded by a system admin to reflect changes. This means that developers must support installations which use an older version of the app manifest until all tenants have upgraded past it.

Delete: Permanently removes the app and all its versions. This action will fail if the app is currently installed in any tenant.

Show secret: Reveals the app secret in a pop-up modal. Apps with UI extensions must use this secret to decode the JWT sent to their UI extension URLs. It is also sent as a header X-Perc-App-Secret in lifecycle callbacks so that the app can authenticate that the callback came from Percolate.

Once registered, you can begin testing your new app by installing it.