Campaigns, querystrings and FXM

So I saw that in Sitecore’s Federated Experience Manager (FXM) campaigns get added to a page by adding a page filter. I came across this great article that shows in detail how to set goals, campaigns and the like.

In any case, I found it a bit strange that a campaign would have to be set as a page filter, rather than being able to link to an affiliate site with the campaign tracker in  the URL like we’re used to in our normal use of Sitecore (e.g. use sc_camp=someguid).

Of course, as with most things Sitecore, we can customize FXM and I figured this would be a nice way for me to get some more experience with FXM.

The most obvious step first of course: Adding the site to FXM. This can be done through the Federated Experience Manager link on the Launch Pad, and you can then click ‘add external website’. In my case I’ve added the website Sandbox FXM with the domain sandbox.fxm.


FXM will then give you a beacon (in the ‘Generated script’ field) which you can parse into your external site. I’ve just dropped mine right before the closing body tag.

Don’t forget to create a site in IIS and update your hosts file as well to make sure you can browse it.

After I pasted that I ran into my first issue: I kept getting the error “Error: Failed to load resource: the server responded with a status of 400 (DomainInvalid)” when loading the FXM site. This has a simple fix: Publish your FXM site, which you can do from the FXM screen.

So, that resolved we can start to write some code. By looking at the TrafficTypeProcessor I found I need to inherit from ITrackPageVisitProcessor and ITrackPageVisitProcessor<ITrackPageVisitArgs>.

Then, in the code I will grab the URL of the page, get the sc_camp querystring from it and register that campaign

public class RegisterCampaignProcessor : ITrackPageVisitProcessor, ITrackPageVisitProcessor<ITrackPageVisitArgs>
    public void Process(ITrackPageVisitArgs args)
        var url = System.Web.HttpContext.Current.Server.UrlDecode(WebUtil.GetRawUrl());
        var campaign = string.Empty;
        if (url.IndexOf("sc_camp=") > 0)
            campaign = url.Substring(url.IndexOf("sc_camp=") + 8, 38);
        if (!string.IsNullOrEmpty(campaign))
            var campaignItem = args.Context.Database.Database.GetItem(campaign);
            if (campaignItem != null)
                CampaignItem item = new CampaignItem(campaignItem);

When we do WebUtil.GetRawUrl() we will actually get back something similar to this:
So I’ll grab the campaign from there – although in a production scenario you might want to be a bit more careful about this because this particular code requires you to have the accolades as part of the campaign id (as well as not having any checks on whether it’s a GUID etc). From that GUID I resolve the campaign item as an Item, create a CampaignItem object from that and trigger that on the campaign.

We can use our Sitecore include files to patch this processor in in the correct place – in my case I’ve patched it right before the TrafficTypeProcessor:

<?xml version="1.0"?>
<configuration xmlns:patch="">
            <group groupName="FXM" name="FXM">
                        <processor patch:before="*[@type='Sitecore.FXM.Pipelines.Tracking.TrackPageVisit.TrafficTypeProcessor, Sitecore.FXM']" type="Sandbox.FXM.TriggerCampaign.RegisterCampaignProcessor, Sandbox" />

So that’s now all well and good but how do I figure out whether it’s working? If I had an empty xDB it would be easy enough but I actually have a lot of dummy data in there so had to be a bit more creative. In Mongo I wrote a query to figure out which data came from FXM:

db.Interactions.find({ "SiteName" : "Sandbox_FXM" }, { "ContactId" : 1 } )

In there, I can see that a campaign has been triggered, but I’d also like to see my xFile, andof course the ContactId is then shown as a binary type 3 value. I’m using MongoVue to view my Mongo data, which actually comes with a very handy option:


Using that I can find the GUID I had for that visitor. I can then open any random xFile and copy/ paste the GUID of this particular Contact in the URL.


Although for the people paying attention: The contact ID is also in the URL we had from running WebUtil.GetRawUrl(). Sadly I couldn’t actually use that in my example as it was a new InPrivate window and I had closed it.