Introduction

Pagehooks are the first feature part of a new set of features under a category called UI Extensibility.

PageHooks are buttons and links that can be configured to launch external applications or services from within the Aprimo UI, such as web applications, Azure functions, etc. They make it possible to use that external service or application to extend the default functionality of Aprimo. PageHooks can be used to simply pass data to an external application or to process data in more advanced ways and return the result back to Aprimo.

Custom actions in Aprimo DAM

PageHooks make it possible to create custom actions on records or collections in Aprimo DAM. By default there already are a number of actions available, such as Edit, Download or Delete, but you might want to create some custom ones that fit your business process better.

When using a PageHook in a custom action, Aprimo DAM simply sends a request and then waits for the external application or service to process it and return a response. DAM acts on this response, from simply showing a success message to redirecting the user to a third party application, which can be opened either in the same window or in a new window.

How do custom actions work

A user clicks the custom action in Aprimo DAM in the action menu of either a single record, a selection of records, or in a collection. This action then posts a request, containing the record or collection id(s), along with the URL of the current page, the location in which to open any response URL and an authorization code (if necessary), to the application endpoint that was specified in the PageHook, e.g.

Contents of a PageHook request
Contents of a PageHook request

The external application or service can then start processing the request. If an authorization code was included, the external application can use this to authenticate and communicate with the DAM API, using the current user’s account.

Except for the record/collection Ids, the PageHook does not send any other DAM data to the external application. It’s up to the endpoint to query the DAM REST API for the additional data it needs.

When the external application has done its work, it sends a response back to DAM: either just a notification that the data was received successfully (optionally including a message), an error message if anything went wrong or a response URL. If there was no URL in the response, Aprimo DAM simply shows a “Success” flyout or the returned error message. If there was a response URL the user is redirected to that URL. Depending on the settings in the PageHook this URL is opened in the same window or in a new one, either refreshing the window or redirecting the user to a different browser window.

Opening the response URL in the same window is recommended if the external application changes data or content in the record where user triggered the action. If the response URL is the same one as the page where the action was clicked, it will simply refresh the record details so the user can see the effects of his action.

Another use case for same window could be redirecting the user to a custom wizard, e.g. to start an approval process on a record in DAM. The wizard takes the user through a series of data collection steps, collecting the data that is required in the approval application but should not be stored in DAM. The external application then retrieves any other necessary data from DAM and submits everything to the approval application for further processing. It ends by either redirecting the user back to a page in DAM or to the item in the approval application, depending on the business process.

If the URL is set to open in a new window, DAM just opens that window and posts the data. The external application is responsible for the contents of that window and DAM is not involved in the processing anymore. The existing DAM window will continue to function normally. A use case could be, for example, publishing a file to a social media channel. In this case the action pops up a new window, the custom code receives the Ids of the record where the action was clicked, queries the DAM REST API for additional data, and uses this data to talk to the API of the social media channel. The user only sees a new window with a prepopulated submission screen from the social media channel.

To summarize, a response can have either of the following contents:

  • A success HTTP code with no other contents, which will trigger an “action completed successfully” notification in the UI.
  • A success HTTP code with a msg property, which will be shown in the UI.
    {
       "msg":"...."
    }
  • A success HTTP code with a url property, which will be opened in a new tab page.
    {
      "url":"https://..."
    }
  • An error HTTP code with no other contents, which will trigger an “action didn’t succeed” notification in the UI.
  • An error HTTP code with an errorMsg property, which will be shown in the UI.
    {
       "errorMsg":"...."
    }

Time-out

Since Aprimo DAM waits for the response from the external application or service, it’s necessary to limit the time this application has to send the response. That is why there is a time-out limit of 15 seconds, between the request and the reception of the response.

Steps to create a custom action using PageHooks

These steps need to be done to create a custom action using a PageHook in DAM:

  1. (optional) Register the external application or service Aprimo MO
  2. Develop the external application or service
  3. Add the custom action to Aprimo DAM
  4. Add translations for the action label for all UI languages in Aprimo DAM

(optional) Register the external application or service in Aprimo MO

Use the Registrations list in the Integration area of Aprimo MO to identify the external applications that can communicate with Aprimo. This is only necessary if the external application needs to authenticate to get data from within DAM.

You can find the Registrations list in System Administration > System Tools > Integration > Registrations.

More information on how to create an application registration is available in https://developers.aprimo.com/marketing-operations/rest-api/authorization/#module3 , in step 1.

Develop the external application or service

PageHooks can work with all kinds of applications or services, like web services, Azure Functions, etc. The only prerequisite is that they should be able to accept HTTP requests from DAM.
You will need the endpoint URL of this service or application to use it in a custom action.

How to authenticate

When the external application gets the request, it will probably need to get more detailed information about the record(s) or collection the action was started from. To be able to do this the application or service needs to authenticate. This can be done either using the user account that clicked the action, or with an integration account of the application itself.

If you want to use the user account that triggered the custom action, configure the PageHook so that it includes an authorization code and the client id (see further). You can then use these to get an authentication token back from Aprimo MO, which you can use to authenticate with DAM and get the data you need. Follow this process  https://developers.aprimo.com/marketing-operations/rest-api/authorization/#module2, but only step 1 (where you register the application to get a client id, see before).

Include these headers in the POST request to get an authentication token back from Aprimo MO:

  • client-id: the client Id of the application registration in Aprimo MO
  • authorization-code: the auth-code that was included in the request URL
  • content-type: application/JSON
  • authorization: a string you get by base64 encoding the concatenation of the client id and the secret, separated by a colon: [ClientId]:[Secret]

If you want the application to log in under its own “integration” account, follow all of the  steps in https://developers.aprimo.com/marketing-operations/rest-api/authorization/#module3. This also means that you don’t need to configure the PageHook to include an authorization code and client id (see further).

Get record/collection data via the ADAM REST API.

Use the ADAM REST API to get record or collection data from within DAM, using the record Id(s)  or collection Id from the request.

You can find more information on how to use the ADAM REST API in https://training3.dam.aprimo.com/api/core/docs

Add the custom action in Aprimo DAM

There are several record or collection-related action menus in Aprimo DAM, and each of them is managed in a separate system setting in ADAM System; If you want to add a custom action, you have to add it in each of the action menu settings where you want it to appear. The settings are:

For records:

  • .assetStudioSearchRecordActions: action menu on a record tile when searching or browsing for records
  • .assetStudioSelectionActions: action menu in the selection bar when one or more records have been selected
  • .assetStudioViewBasketRecordActions: action menu on a record tile in a collection
  • .assetStudioViewRecordActions: action menu when viewing a record’s details

For collections:

  • .assetStudioSearchBasketActions: action menu on a collection tile when searching or browsing for collections
  • .assetStudioViewBasketActions: action menu when viewing a collection’s details

To add a custom action that uses a PageHook you edit the appropriate setting in ADAM System, and you add this line in the list of actions in the XML structure:

<add type=”Adam.Web.Extensions.Providers.Actions.PageHookAction, Adam.Web.Extensions”
     name=”MyCustomAction”
     include=”auth-code”
clientId=”[client id]”

     url=”[service url]”
     location=”[self | new]” />

where:

  • name: provide a unique name for this action. This name is used to identify the action, not shown to the user. Action label translations (see further) are used in the Aprimo DAM UI.
  • include=”auth-code”: (optional) add this argument to include an authorization code in the request. This code, together with the client id, allows the external application or service to authenticate and communicate with Aprimo DAM, using the credentials of the user that triggered the action.
  • clientID: the client Id of the external application or service, as configured in Aprimo MO. This argument is only necessary in case the auth-code was included.
  • url: the URL of the endpoint of the external application or service
  • location: indicate if the response URL from the external app or service should be opened in the same window (location=”self”) or in a new one (location=”new”).

For more information on these action menu settings and the action menu structure you can use the Help link in each of these settings or go into ADAM Help > Administrator Guide > Configuration areas > UI configuration in ADAM studios > Configuring action menus for records and collections.

Provide translations for the action label

To provide a label for your custom action in all UI languages in Aprimo DAM, you have to create the corresponding translations in ADAM System, with these specifications:

  • Studio = Providers
  • Module = ActionNames
  • Name = YourCustomActionName
  • Translations: the translated label for the custom action in the necessary languages

For more information on how to create translations in ADAM System you can use the Help on this page link in the Translations area in ADAM System or go into ADAM Help > Administrator Guide > Configuration areas > Localization > Translations.

Code example

This example illustrates how the request and response mechanism works between an Azure function and Aprimo DAM PageHooks. It’s not at all meant to be useable as a real application, but gives you an idea how the different types of interaction work and can be handled.

Create an Azure function

In this example we’ll create two functions: one that returns a success code and redirects the user to a website, and one that returns an error code and a custom error message.

To do this you should first create a Function App in the Azure portal. In this function app, create two functions:

  1. A function that returns a success code and a URL

This is some sample code for the first function, which returns a success code and a URL to redirect users to:

using System.Net;
using System.Net.Http.Formatting;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    log.Info("Pagehook success function processed a request.");

    // The response will contain a URL to redirect users to
    var wrap = new { url = "https://www.aprimo.com", errorMsg = "" };

    // The function returns a "success" code, together with the URL
    var response = req.CreateResponse(HttpStatusCode.OK, wrap, JsonMediaTypeFormatter.DefaultMediaType);
    response.Headers.Add("Access-Control-Allow-Origin", "*");
       
    return response;
}

2. A function that returns a custom error message

This is some sample code for the second function, which returns a custom error message:

using System.Net;
using System.Net.Http.Formatting;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    log.Info("Pagehook custom error function processed a request.");

    // The response will contain a custom error message
    var wrap = new { url = "", errorMsg = "This is a custom error." };

    // The function returns the custom error message
    var response = req.CreateResponse(HttpStatusCode.OK, wrap, JsonMediaTypeFormatter.DefaultMediaType);
    response.Headers.Add("Access-Control-Allow-Origin", "*");
       
    return response;
}

You can test the functions by clicking the Run button. The resulting output should look like this:

{“url”:”https://www.aprimo.com”,”errorMsg”:””}

for the first function, or

{“url”:””,”errorMsg”:”This is a custom error.”} 

for the second function.

Whitelist the Aprimo DAM server to enable Cross-Origin Requests (CORS)

By default the Azure App Service blocks calls to function apps from external sources. That is why you have to add your Aprimo DAM environment to the cross-origin resource sharing (CORS) “whitelist” of allowed origins from which your functions can accept remote requests.

In Azure Portal open your function app and choose the tab Platform features. In API click CORS to open the CORS settings. Add the URL to your Aprimo DAM environment to the list of allowed origins, e.g. https://yourDAM.aprimo.com. Click Save at the top to save your changes.

Register the function in Aprimo MO, to get the necessary client ID.

See above for more information.

Create the custom actions in Aprimo DAM

Choose one of the action menu settings in Aprimo DAM to add the custom actions to, e.g. the .assetStudioSearchRecordActions setting controls the action menu on the Assets Browse pages.

see above for the complete list of action menu settings.

Add the following lines to add two actions that call the functions that you created above:

  1. This action sends the request to the first function, shows a “Success” flyout message in Aprimo DAM and redirects the user to www.aprimo.com in a new window

<add type=”Adam.Web.Extensions.Providers.Actions.PageHookAction, Adam.Web.Extensions”
       name=”PageHook.Action”
       url=”https://yourfunctionapp.azurewebsites.net/api/AdamPagehookSuccessURL”
       location=”new”
/>

  1. This action sends the request to the second function, and gets a custom error messge back which is shown to the user in an error message dialog.

<add type=”Adam.Web.Extensions.Providers.Actions.PageHookAction, Adam.Web.Extensions” 
       name=”PageHook.ErrorAction”
       url=”https://yourfunctionapp.azurewebsites.net/api/AdamPagehookCustomError”
/>

Add labels in the translations of Aprimo DAM

In System, go to Translations. There will already be one PageHook related translation: “PageHook.Title”, which is the translation used by Pagehooks as the default label when a label has not been defined.

Create a new translation using the action name you specified and provide a label for the action in each of the languages that you use in DAM. Save the translation.

If you now go to Assets, go to Browse and click the action menu icon on one of the record tiles on the page, your actions should be available:

Action menu with custom actions
Action menu with custom actions

If the custom action is not visible, you may need to have the translation cache reset by an Operator.