About intents
The intents mechanism is one way to extend an app's functionality. An intent is a message object you define in an app that allows you to pass the user flow from one app to another. We've many reasons for sending intents. For example:
- Share a chart with the Dashboard app
- Show details of an app based on the
appId
- Create a new JIRA ticket and get the ticket ID
Lifecycle of an intent
There are three elements involved in the intent mechanism:
- Source app: Sends an intent to another app
- Target app: Receives the intent and acts on the intent
- AppShell: Handles the communication between the source and the target app.
Here is what happens when a source app sends an intent:
-
The source app sends the request to AppShell, for example, using the
sendIntent
method from@dynatrace-sdk/navigation
. The communication uses thewindow.postMessage
API. -
The AppShell allows users to select an app from a list of apps that can handle the intent.
-
The AppShell opens the target app in an iframe and passes the intent as query arguments in the URL.
-
The target app can perform any action on the received intent.
Structure of an intent payload
An intent payload is a set of key-value pairs that contains information you want to share.
Examples
Here are some examples of intent payload objects:
const intentPayload = {
'dt.entity.host': 'HOST-F66B242CD3A5E38E',
};
const intentPayload = {
'dt.query': 'timeseries avg(cpu.temperature)',
'dt.timeframe': {
from: 'now-2h',
to: 'now',
},
};
Main elements of the intent mechanism
Source app
The source app sends the actual intent to the AppShell.
- To learn more about how to send an intent, see the Send intents guide
Target app
The target app is the app that receives an intent. Each target app has to define the type of intents it can receive in the app configuration file. It can then perform some action on the received intent.
- Learn more about receiving an intent in the Receive intents guide.
- Learn more about the content in the app configuration file in the Dynatrace App Toolkit reference.
AppShell
The AppShell handles the intent sent by the source app.
-
The AppShell finds a target app as follows:
- Shows the
Open with...
dialog to let the user choose a target app - Shows an empty state dialog if no app can handle the intent
- Shows the
-
The AppShell launches the target app of the given
appId
. -
The AppShell uses URL query arguments to pass the intent object synchronously to the target app as initialization data.
Matching intent with apps
The AppShell finds installed apps capable of handling a specific intent by validating the intent object against the intents declared in the app configuration file. The validation mechanism matches the intent payload with the required properties of an intent defined in the target app. The target app defines each intent using a unique intent ID.
In the following example, a target app declares two intents with intent ID query-existing
and query-new
.
{
"intents": {
"query-existing": {
"description": "Add a query to existing notebook",
"properties": {
"dt.query": {
"required": true,
"schema": {
"type": "string"
}
}
}
},
"query-new": {
"description": "Add a query to a new notebook",
"properties": {
"dt.query": {
"required": true,
"schema": {
"type": "string"
}
}
}
}
}
}
Full example
- app.config.json
- app.config.ts
{
"environmentUrl": "<Your-Environment-URL>",
"app": {
"id": "<Your-App-ID>",
"name": "<Your-App-Name>",
"version": "0.0.0",
"description": "<Your-App-Description>",
"scopes": [],
"intents": {
"query-existing": {
"description": "Add a query to existing notebook",
"properties": {
"dt.query": {
"required": true,
"schema": {
"type": "string"
}
}
}
},
"query-new": {
"description": "Add a query to a new notebook",
"properties": {
"dt.query": {
"required": true,
"schema": {
"type": "string"
}
}
}
}
}
}
}
import type { CliOptions } from 'dt-app';
const config: CliOptions = {
environmentUrl: '<Your-Environment-URL>',
app: {
id: '<Your-App-ID>',
name: '<Your-App-Name>',
version: '0.0.0',
description: '<Your-App-Description>',
scopes: [],
intents: {
'query-existing': {
description: 'Add a query to existing notebook',
properties: {
'dt.query': {
required: true,
schema: {
type: 'string'
}
}
}
},
'query-new': {
description: 'Add a query to a new notebook',
properties: {
'dt.query': {
required: true,
schema: {
type: 'string'
}
}
}
}
}
}
}
module.exports = config;
Both of these intents have the same properties. If an app sends dt.query
via an intent, the target app will be listed twice on the Open with
dialog. The user can select a specific action in the target app the app will pass via the intent app route using /intent/:intentId
.
The target app only has access to properties defined in its intent declaration. The AppShell removes additional properties sent by the source app.
Limitations
- The URL length: The AppShell creates the URL for each intent as a query argument. In this case, the URL length depends on the intent's definition. There is no length standard for the URL. However, here is what our tests indicated:
- Modern browsers can handle up to 2 MB. Address bars are limited to 32 KB.
- Many mobile browsers become unresponsive for links longer than 16 KB.