Report plugins
Types of report plugins
Report plugins come in three types:
- Timeseries report plugins — For example forecasting for the next week, based on the last 180 days. This needs a report per
hour
,day
,week
ormonth
as plugin data. - User report plugins — For example A/B testing for the 7 days, based on the last 180 days. This needs any report (except for Event report) per
total
and grouped byUser -> ID
as plugin data. - Event report plugins — For example anomaly detection of some event. This only works with an Event report per
total
and grouped byEvent -> ID
as plugin data.
Report values, e.g. conversion rates, event counts and more, are supplied as plugin parameters via their relative value index. So the first value is index 0, the second is 1, etc. The Report api-library documentation shows exactly for which report types which relative value index is used.
Similarly any group-by is addressed using it's own relative group-by index — the first group-by used being index 0, etc. The param must use the format {groupByIndex: 0}
instead of a simple number instead. The code example for the Users plugin below will make this clear.
Running a plugin is done by calling the async function PluginData.get
, with its first parameter being a permalink string pointing to the plugin to run. The permalink may be prefixed with a name and a /
character which means it's an external (third-party) plugin that is not part of the current Template.
The second argument is an options object. The options object generally contains two keys.
One for data
, which can be either a report object, or a string containing a bookmark ID. This is the same as what is described in the previous page on working with Reports.
The other one is params
, an object containing a key/value pair of plugin input parameters.
The easiest way to get a quick code example of how to use a specific plugin and all its input parameters, is to visit the Insight creation or edit page. Then select from the Example code:
dropdown a local or third-party plugin.
The next sections show code examples of each of the three plugin types.
Timeseries plugin
A timeseries report plugin may only work with a report with its time unit set per hour, day, week or month. Some timeseries plugins may work with all date granularities — this will be indicated by a comment when using the Example code:
dropdown, as well if it only supports one specific date granularity.
The first argument "plugins/forecast"
means we run a third-party forecast plugin.
The second arguments has data
using a custom Event Report counting event_a
over the last 180 days.
The params
supplies the two parameters this plugin has:
forecast_value
— plugin input data, which comes directly from the report. Because report results are value based, this argument indicates the value index to use as the numerical value for the time series.forecast_periods
— a simple numeric value as plugin parameter, indicating the number of days to forecast.
Or simply using a bookmarked report as data input. The bookmark ID can be looked up through the Example code:
dropdown.
Users plugin
A user report plugin only works with a report with its time unit set per total
, and the group-by on at least the id
property of users
. It works for any report type, except for the Event Graph
report.
Here is an example of running a user report plugin, such as A/B testing, based on the conversion rate of the second funnel step event_b
.
An additional group-by is set to a user text property, indicating the button color variation. Note the param format to indicate a relative group-by index is done using {groupByIndex: 1}
. By default a value index is indicated by a simple number, but we can use the alternative format of {valueIndex: 0}
as well.
Events plugin
Event report plugin only works with report the Event Graph
report, its time unit set per total
and the group-by on at least the id
property of events
.
Because event plugins have access to the individual events, they are often used for things like anomaly detection.
Here is an example of running an event report plugin based on a full list of all events event_a
. The group-by is set as required for event plugins to the id
of events
. Additionally a group-by is added to access the timestamp of the event:
Optional plugin parameters
Some plugin params
can be optional such as sensitivity
and forecast_additional_value
in the example below, indicated by the comment // Optional
when looking up the example code:
When an optional param is not supplied at all, and it is of a simple type (number/text/boolean/date), it will be given its default value. For optional input data, the field is not used at all if left out. Thus in the example below the optional parameters sensitivity
and forecast_additional_value
are not supplied, and for sensitivity
it ends up using the default value of 5
, while forecast_additional_value
will not be used at all:
In order to not use an optional param at all, supply null
as value. For input data params we can either leave the param out or set it to null
— in both cases the param will be unused because input data doesn't have a default value. See example below:
Plugin helper functions
Often plugins come with helper functions. Helpers prevent code duplication and make it easy to display certain parts of a plugin output, such as a line-chart displaying the forecast.
Helper functions are accessible directly on the plugin result object, under the helpers
object. When a plugin has documented helpers, they will be shown when you choose the plugin from the Example code:
dropdown.
Here is an example using the renderAll()
helper function from the forecast plugin to display charts and text that come along with visualizing the forecast results:
Here is an example plugin shown its documented helper functions:
Custom SQL
For some cases working with the Report
objects might not be possible, because it simply cannot generate the kind of data you want. In that case you can use a fully custom SQL query, which can be used as an input to any report plugin.
Before you can use custom SQL as plugin input data, you need to map SQL column names to a format so that the API understands which ones are values, group-by's, segments and such. This and more, like working with dynamic date ranges using custom SQL, can be found in the Report - Custom SQL section of the api-library.
In the end, custom SQL reports are just report objects, so once your SQL query uses the correct column mapping, it can be used as follows:
In addition a bookmarked SQL report ID can also be supplied:
Error handling
For plugins it's important to first check if there is an error before continuing with any code that depends on and comes after the plugin is executed.
Because a failed PluginData.get
returns an error object, we can return it directly in the JS code. As explained in the adding code page, an error object can be returned directly, so that it gets picked up and the error is shown to the end-user.
To check if the plugin has an error we first need to use Utils.validResult(pluginResults)
. This is usually the preferred way, because plugins usually return more detailed and actionable errors for the end-user:
Alternatively we can return a string directly, which is displayed as error to the end-user:
Or we can return an error object with more details:
Notifications
Some plugins may generate notifications. You can check if there are any by using the notifications
property of the plugin results object.
Normally notifications from individual plugins do not end up as Insight notifications, so effectively they will stay hidden.
This allows you to decide in the Insight which notifications from which plugins you want to be visible or filter out, instead of all notifications from all plugins automatically showing up all the time.
To pass through notifications from a plugin to the Insight, use the following code:
The notifications
property of the plugin result is an array of notification objects, similarly to what is described in the Insight Notifications section.
Additionally you can loop through the notifications
array, and add only only high-priority ones or with status warning
, for example:
Caching
Plugin results can be cached so that on the next run we get the results directly without waiting. This is most often used for intelligence plugins though, but report plugins can use the same strategy.
Any PluginData.get
call can have in the options object a setCache
.
If getCache
doesn't have a cached result yet, it will first run the plugin as-is and then store the results on the cache key.
Both getCache
and setCache
have one argument; the cache key as string. The cache key can be made up of the timestamp truncated to the day, week, etc. so we only get fresh results once per some period.
Each plugin run that uses setCache
overwrites any previous cached version using the same cache key.
One scenario would be an Insight that can be subscribed to that uses setCache
to cached some plugin result on a regular basis in the background regularly, see example below:
Then a non-standalone Insight that uses getCache
to get the plugin results, see example below. Note the getCache
instead of setCache
. In addition, we should use the same code as for the setCache
example because if the end-user runs the Insight when the getCache
one has not been executed yet, it will just run the plugin as that time and store the cached results:
Limitations
note
PluginData.get
cannot be executed in parallel at the moment, but this will be fixed in the near future.
If you have multiple PluginData.get
calls or use Promise.all
, you have execute them synchronously one after another instead: