Custom Campaign Selection - BloomReach Experience - Open Source CMS

Custom Campaign Selection

This feature is available since BloomReach Experience Manager 13.1.0



Implement a custom heuristic to choose from multiple campaigns running concurrently.

Multiple Campaigns Running Concurrently

If, at a certain point in time, there are multiple campaigns running concurrently for the same channel, then by default the campaign that has the shortest running period will be served to visitors of that channel. For example, if today it is the 13th of February, and the following three campaigns are started but not yet stopped:

  1. Campaign 1: Started at 12th of February and runs until the 28th of February
  2. Campaign 2: Started at 9th of February and runs until the 14th of February
  3. Campaign 3: Started at 7th of February and runs until the 28th of February

Then Campaign 2 will be served because it has started, has not yet stopped, and has the shortest running period. This is how the default heuristic to choose between multiple campaigns running concurrently is implemented. Developers of end projects can however provide a different heuristic which can be injected to override the default heuristic. If, for example, you have a requirement to serve a different campaign, say, based on the location of the visitor (e.g. serve different campaigns in the US and in Europe), this can be achieved in this way.

Implement Custom Campaign Selection

Per HST Site webapp, one single custom campaign selector can be injected via providing a HstSiteProvider implementation and wiring it as a Spring bean in an XML file at:


For example in custom-hst-site-provider.xml you can have:

<beans xmlns=""

  <bean class="com.myproject.campaigns.LocationBasedHstWebSiteProvider"/>


The LocationBasedHstWebSiteProvider class must implement For example:

public class LocationBasedHstWebSiteProvider implements HstSiteProvider {

    private final ProjectService projectService;

    public LocationBasedHstWebSiteProvider() {
        projectService = HippoServiceRegistry.getService(ProjectService.class);

    public HstSite getHstSite(final HstSite master, 
                              final Map<String, HstSite> branches, 
                              final HstRequestContext requestContext) {

        if (branches.isEmpty()) {
            return master;

        final List<Project> eligibleCampaigns = new ArrayList<>();
        for (Project project : projectService.getProjects().values()) {
            if (ProjectState.RUNNING.equals(project.getState())) {

        final String ip = HstRequestUtils
        // TODO implement your own geoIpService returning a Location object
        final Location location = geoIPService.getLocation(ip);

        final String contentinentCode = location.getContinentCode();

        for (Project eligibleCampaign : eligibleCampaigns) {
            // if there is a continent match with project name, serve that campaign
            if (contentinentCode.equals(eligibleCampaign.getName())) {
                final HstSite hstSite = branches.get(eligibleCampaign.getId());
                if (hstSite == null) {
                    return master;
                return hstSite;
        // no continent match....serve either some eligibleCampaign or return master

        return master;

The above logic can serve a different campaign per continent assuming you implement your own geoIpService returning a Location object based on the IP address of the visitor.

Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?