Enabling click tracking on URLs other than the indexed live url

Background

Funnelback’s click tracking feature includes in-built security that prevents redirection to an arbitrary URL. Click tracking, while not required, enables Funnelback to learn from user behaviour and modify result ranking. Click tracking is also used for the top click reports within the analytics.

There are some valid situations where you wish to redirect to a URL that doesn’t match the indexed URL for the document, but still capture the click. This redirect could be to an external URL or a URL that is contained within a metadata field (e.g. if the indexer has assigned internal URLs as occurs when indexing database content and some XML data).

This page describes how this redirection can be achieved with click tracking support.

Process

Create a hook_post_datafetch.groovy hook script that modifies the live URL on the collection that is being queried (have a look to see what the collection parameter is when you run the search). This modification must occur in post datafetch (not post process) because the click tracking link includes an encoded version of the live URL which is calculated after the post datafetch phase completes.

At a basic level all that is required is to update the value of the liveUrl parameter for the item from a post datafetch hook script.

the URL needs to be updated using a post datafetch hook script (as opposed to a post process hook script) because the click tracking URL is calculated from the liveUrl value before the post process hook script runs. If you update the liveUrl in a post process hook script the clickTrackingUrl will not be updated.

This example sets the live URL to be sourced from a metadata field called customUrl

hook_post_datafetch.groovy
if ( transaction.response != null
  && transaction.response.resultPacket != null) {
    transaction.response.resultPacket.results.each() {
        if (it.metaData["customUrl"] != null) {
            it.liveUrl =  it.metaData["customUrl"]
        }
    }
}

The transformation can be more complicated - a more advanced example shows the URL being updated to pass in some extra parameters.

hook_post_datafetch.groovy
import java.net.URLEncoder;
if ( transaction.response != null
  && transaction.response.resultPacket != null) {
    transaction.response.resultPacket.results.each() {

        def parameter = ''

        if ( it.liveUrl.contains("?") ) {
            parameter = "&";
        } else {
            parameter = "?";
        }

        // In Groovy, "it" represents the item being iterated
        it.liveUrl = it.liveUrl + parameter + 'fb_keyword=' + URLEncoder.encode(transaction.question.query);
    }
}