Creating Custom Extensions creating-custom-extensions

CAUTION
AEM 6.4 has reached the end of extended support and this documentation is no longer updated. For further details, see our technical support periods. Find the supported versions here.

Generally when you implement a project, you have custom code in both AEM and Adobe Campaign. With the use of the existing API, you can call your custom code in Adobe Campaign from AEM or from AEM to Adobe Campaign. This document describes how to do that.

Prerequisites prerequisites

You need to have the following installed:

  • Adobe Experience Manager
  • Adobe Campaign 6.1

See Integrating AEM with Adobe Campaign 6.1 for more information.

Example 1: AEM to Adobe Campaign example-aem-to-adobe-campaign

The standard integration between AEM and Campaign is based on JSON and JSSP (JavaScript Server Page). These JSSP files can be found in the Campaign console, and all start with amc (Adobe Marketing Cloud).

chlimage_1-15

NOTE
For this example, please see Geometrixx, which is available from Package Share.

In this example, we create a new custom JSSP file and call that from the AEM side to retrieve the result. This can be used, for example, to retrieve data from Adobe Campaign or to save data into Adobe Campaign.

  1. In Adobe Campaign, to create a new JSSP file, click the New icon.

  2. Enter the name of this JSSP file. In this example, we use cus:custom.jssp (meaning it will be in the cus namespace).

    chlimage_1-16

  3. Put the following code inside the jssp-file:

    code language-none
    <%
    var origin = request.getParameter("origin");
    document.write("Hello from Adobe Campaign, origin : " + origin);
    %>
    
  4. Save your work. The remaining work is in AEM.

  5. Create a simple servlet on the AEM side to call this JSSP. In this example, we assume the following:

    • You have the connection working between AEM and Campaign
    • The campaign cloudservice is configured on /content/geometrixx-outdoors

    The most important object in this example is the GenericCampaignConnector, which allows you to call (get and post) jssp files on the Adobe Campaign side.

    Here is a small code snippet:

    code language-none
    @Reference
    private GenericCampaignConnector campaignConnector;
    ...
    Map<String, String> params = new HashMap<String, String>();
    params.put("origin", "AEM");
    CallResults results = campaignConnector.callGeneric("/jssp/cus/custom.jssp", params, credentials);
    return results.bodyAsString();
    
  6. As you see in this example, you need to pass in the credentials into the call. You can get this via the getCredentials() method where you pass in a page that has the Campaign cloud service configured.

    code language-xml
    // page containing the cloudservice for Adobe Campaign
    Configuration config = campaignConnector.getWebserviceConfig(page.getContentResource().getParent());
    CampaignCredentials credentials = campaignConnector.retrieveCredentials(config);
    

The complete code is as follows:

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;

import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.day.cq.mcm.campaign.CallResults;
import com.day.cq.mcm.campaign.CampaignCredentials;
import com.day.cq.mcm.campaign.GenericCampaignConnector;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.day.cq.wcm.api.PageManagerFactory;
import com.day.cq.wcm.webservicesupport.Configuration;

@SlingServlet(paths="/bin/campaign", methods="GET")
public class CustomServlet extends SlingSafeMethodsServlet {

 private final Logger log = LoggerFactory.getLogger(this.getClass());

 @Reference
 private GenericCampaignConnector campaignConnector;

 @Reference
 private PageManagerFactory pageManagerFactory;

 @Override
 protected void doGet(SlingHttpServletRequest request,
   SlingHttpServletResponse response) throws ServletException,
   IOException {

  PageManager pm = pageManagerFactory.getPageManager(request.getResourceResolver());

  Page page = pm.getPage("/content/geometrixx-outdoors");

  String result = null;
  if ( page != null) {
   result = callCustomFunction(page);
  }
  if ( result != null ) {
   PrintWriter pw = response.getWriter();
   pw.print(result);
  }
 }

 private String callCustomFunction(Page page ) {
  try {
   Configuration config = campaignConnector.getWebserviceConfig(page.getContentResource().getParent());
   CampaignCredentials credentials = campaignConnector.retrieveCredentials(config);

   Map<String, String> params = new HashMap<String, String>();
   params.put("origin", "AEM");
   CallResults results = campaignConnector.callGeneric("/jssp/cus/custom.jssp", params, credentials);
   return results.bodyAsString();
  } catch (Exception e ) {
   log.error("Something went wrong during the connection", e);
  }
  return null;

 }

}

Example 2: Adobe Campaign to AEM example-adobe-campaign-to-aem

AEM offers out of the box APIs to retrieve the objects available anywhere in the siteadmin explorer view.

chlimage_1-17

NOTE
For this example, please see Geometrixx, which is available from Package Share.

For each node in the explorer there is an API that is linked to it. For example for the node :

the API is:

The end of the URL .1.json can be replaced by .2.json, .3.json, according to the number of sub-levels you interested in getting To obtain all of them the keyword infinity can be used:

Now to consume the API we must know that AEM, by default, uses basic authentification.

A JS library that is named amcIntegration.js is available in 6.1.1 (build 8624 and higher) that implements that logic among several other ones.

AEM API call aem-api-call

loadLibrary("nms:amcIntegration.js");

var cmsAccountId = sqlGetInt("select iExtAccountId from NmsExtAccount where sName=$(sz)","aemInstance")
var cmsAccount = nms.extAccount.load(String(cmsAccountId));
var cmsServer = cmsAccount.server;

var request = new HttpClientRequest(cmsServer+"/content/campaigns/geometrixx.infinity.json")
aemAddBasicAuthentication(cmsAccount, request);
request.method = "GET"
request.header["Content-Type"] = "application/json; charset=UTF-8";
request.execute();
var response = request.response;
recommendation-more-help
2315f3f5-cb4a-4530-9999-30c8319c520e