Piano (previously ATI) Delegate
This delegate reports analytics events to Piano (previously AT Internet or ATI). It should be noted that in the codebase we still use the reference “ATI”.
It is disabled by default so you will need to enable it before stats are sent to Piano. You will need to ensure that you are reporting the correct Destination value as that determines which Piano Site your data ends up in. The default Echo behaviour is to report into the “Default Site” account.
Most reporting to Piano uses existing functionality that has been set up already for reporting to ComScore. The following are some new features that support reporting to Piano, that you may wish to configure in addition to what you already have.
Table of contents
- Enabling Piano reporting
- Destination
- Producer
- Nations Producer
- Section
- Site variables
- Custom properties
- Handling DeepLinks
- Campaign tracking
- AV reporting
- User Action Events
- Cookies
Enabling Piano reporting
Reporting to Piano is now enabled by default. If for any reason you need to disable it, you can set the ATI_ENABLED
config option to false.
Destination
Instead of using Reporting Profiles, Echo simply needs the Destination for your Site. If you don’t set a Destination your data will end up in the Default Site.
When you set a Destination a Producer value will be set automatically to correspond to your chosen Destination. You can however override this (see below).
var conf = { };
conf[ConfigKeys.DESTINATION] = Enums.Destinations.FOOD;
// Instantiate EchoClient
var echo = new EchoClient('MyApp', Enums.ApplicationType.WEB, conf);
HashMap<String, String> config = new HashMap();
config.put(EchoConfigKeys.DESTINATION, Destination.FOOD.toString());
// Instantiate EchoClient
EchoClient echo = new EchoClient(
"MyApp", // App Name
ApplicationType.MOBILE, // App type
"echo.android.test", // App Countername
getApplicationContext(), // The Android Context of your Application
config, // config options HashMap
bbcUser, // BBCUser instance
this // Application instance of your Application
);
var config:Dictionary<EchoConfigKey, String>
config[.destination] = .Food
// Instantiate EchoClient
do {
echo = try EchoClient(appName: "EchoDemoApp",
appType: .mobileApp,
startCounterName: "bbc.start.page",
config: config,
bbcUser: user)
} catch {
// Handle Echo config error
}
Maintaining the Account User Journey
In order to maintain user journeys through the account sign in process, BBC Account require a userOrigin
parameter from customer facing products in order to attribute events to that destination. userOrigin
is passed as a query string parameter by the product when they refer the user to BBC Account pages. E.G:
https://account.bbc.com/account?ptrt=https%3A%2F%2Fwww.bbc.co.uk%2F&context=HOMEPAGE&userOrigin=HOMEPAGE_PS
If userOrigin
is not set correctly the destination will be assigned as follows:
- If the product sets a
userOrigin
that matches a valid destination, events will be assigned to the product destination, as expected - If the product sets a
userOrigin
that doesn’t match a valid destination, events will be assigned to the BBC Default destination. - If the the product does not set a
userOrigin
events will be assigned to the Account destination.
See the table below for the full list of destination names.
Producer
The Producer value identifies the origin of the content in question. It will be set to a default value that corresponds to your chosen Destination. These defaults are listed below, along with the Piano Site ID for each Destination (the s
value in the request to Piano):
Destination Name | Piano Site ID | Default Producer |
---|---|---|
DEFAULT | 596068 | BBC |
ACCOUNT | 598250 | ACCOUNT |
ACCOUNT_TEST | 598252 | ACCOUNT |
PS_ARCHIVE_SEARCH | 632030 | BBC |
AUDIENCE_PORTAL | 602136 | AUDIENCE_SERVICES |
AUDIENCE_PORTAL_TEST | 602137 | AUDIENCE_SERVICES |
AUDIENCE_SERVICES_PS | 602167 | AUDIENCE_SERVICES |
AUDIENCE_SERVICES_PS_TEST | 602168 | AUDIENCE_SERVICES |
BBC_ARCHIVE_PS | 605565 | BBC_ARCHIVE |
BBC_ARCHIVE_PS_TEST | 605566 | BBC_ARCHIVE |
BBC_CORPORATE_PS | 603550 | BBC |
BBC_CORPORATE_PS_TEST | 603551 | BBC |
BBC_STUDIOS_PLAYER | 606296 | BBC_STUDIOS |
BBC_STUDIOS_PLAYER_TEST | 606293 | BBC_STUDIOS |
BBC_SYNDICATION | 601718 | BBC |
BBC_SYNDICATION_TEST | 601719 | BBC |
BBC_THREE | 598255 | BBC_THREE |
BBC_THREE_TEST | 598256 | BBC_THREE |
BBCS_BBC | 637014 | BBC_STUDIOS |
BBCS_BBC_TEST | 637015 | BBC_STUDIOS |
BITESIZE | 598257 | BITESIZE |
BITESIZE_TEST | 598258 | BITESIZE |
BLOGS_PS | 603546 | BBC |
BLOGS_PS_TEST | 603547 | BBC |
BRITBOX | 598259 | BRITBOX |
BRITBOX_TEST | 598260 | BRITBOX |
CBBC | 598261 | CBBC |
CBBC_TEST | 598262 | CBBC |
CBEEBIES | 598263 | CBEEBIES |
CBEEBIES_TEST | 598264 | CBEEBIES |
FEATURE_SITES_GNL | 598265 | GNL_HOMEPAGE |
FEATURE_SITES_GNL_TEST | 598266 | GNL_HOMEPAGE |
FOOD | 598267 | BBC_FOOD |
FOOD_TEST | 598268 | BBC_FOOD |
GAMES_PS | 599452 | BBC |
GAMES_PS_TEST | 599454 | BBC |
GATEWAY | 598269 | GATEWAY |
GATEWAY_TEST | 598270 | GATEWAY |
HOMEPAGE_GNL | 598271 | GNL_HOMEPAGE |
HOMEPAGE_GNL_TEST | 598272 | GNL_HOMEPAGE |
HOMEPAGE_PS | 598273 | PS_HOMEPAGE |
HOMEPAGE_PS_TEST | 598274 | PS_HOMEPAGE |
IDEAS | 598275 | BBC |
IDEAS_TEST | 598276 | BBC |
IPLAYER | 598277 | IPLAYER |
IPLAYER_TEST | 598278 | IPLAYER |
MEDIA_ACTION | 598279 | MEDIA_ACTION |
MEDIA_ACTION_TEST | 598280 | MEDIA_ACTION |
MONITORING | 598281 | MONITORING |
MONITORING_TEST | 598282 | MONITORING |
MUSIC | 598283 | BBC_MUSIC |
MUSIC_TEST | 598284 | BBC_MUSIC |
NATIONAL_MOMENTS_PS | 605567 | BBC |
NATIONAL_MOMENTS_PS_TEST | 605568 | BBC |
NEWS_PS | 598285 | NEWS |
NEWS_PS_TEST | 598286 | NEWS |
NEWS_GNL | 598287 | NEWS |
NEWS_GNL_TEST | 598288 | NEWS |
NEWS_LANGUAGES_GNL | 598289 | NEWS |
NEWS_LANGUAGES_GNL_TEST | 598290 | NEWS |
NEWS_LANGUAGES_PS | 598291 | NEWS |
NEWS_LANGUAGES_PS_TEST | 598292 | NEWS |
NEWSROUND | 598293 | NEWSROUND |
NEWSROUND_TEST | 598294 | NEWSROUND |
OTHER | 598295 | OTHER |
OTHER_TEST | 598297 | OTHER |
OTHER_EVENT_CATALOGUE | 643514 | BBC |
OTHER_EVENT_CATALOGUE_TEST | 643515 | BBC |
OTHER_EXPERIMENTATION | 643363 | BBC |
OTHER_EXPERIMENTATION_TEST | 643364 | BBC |
OTHER_TELESCOPE | 643361 | BBC |
OTHER_TELESCOPE_TEST | 643362 | BBC |
OTHER_TIPO | 643367 | BBC |
OTHER_TIPO_TEST | 643368 | BBC |
OTHER_VIVO | 643365 | BBC |
OTHER_VIVO_TEST | 643366 | BBC |
OWN_IT | 598298 | CBBC |
OWN_IT_TEST | 598299 | CBBC |
PROGRAMMES_PS | 598300 | PROGRAMMES |
PROGRAMMES_PS_TEST | 598301 | PROGRAMMES |
PS_PAN_BBC | 641476 | BBC |
PS_PAN_BBC_TEST | 641477 | BBC |
RED_BUTTON_PS | 601192 | BBC |
RED_BUTTON_PS_TEST | 601193 | BBC |
REWIND_PS | 603552 | BBC |
REWIND_PS_TEST | 603553 | BBC |
R_AND_D_PS | 607103 | RD |
R_AND_D_PS_TEST | 607104 | RD |
SEARCH_GNL | 598302 | SEARCH |
SEARCH_GNL_TEST | 598303 | SEARCH |
SEARCH_PS | 598304 | SEARCH |
SEARCH_PS_TEST | 598305 | SEARCH |
SILVER_PS | 607105 | BBC |
SILVER_PS_TEST | 607106 | BBC |
SOUNDS | 598306 | SOUNDS |
SOUNDS_TEST | 598307 | SOUNDS |
SPORT_GNL | 598308 | SPORT |
SPORT_GNL_TEST | 598309 | SPORT |
SPORT_PS | 598310 | SPORT |
SPORT_PS_TEST | 598311 | SPORT |
STORYWORKS_GNL | 598312 | GNL_STORYWORKS |
STORYWORKS_GNL_TEST | 598313 | GNL_STORYWORKS |
SUBTITLES_PS | 603548 | PROGRAMMES |
SUBTITLES_PS_TEST | 603549 | PROGRAMMES |
SYNDICATION_PARTNERS_GNL | 598314 | WS_PARTNERS_B2B |
SYNDICATION_PARTNERS_GNL_TEST | 598315 | WS_PARTNERS_B2B |
TASTER | 598316 | TASTER |
TASTER_TEST | 598317 | TASTER |
TEACH | 598318 | BBC |
TEACH_TEST | 598320 | BBC |
TOPICS_GNL | 612991 | BBC |
TOPICS_GNL_TEST | 614559 | BBC |
TOPICS_PS | 612261 | BBC |
TOPICS_PS_TEST | 612262 | BBC |
VOICE | 598326 | VOICE |
VOICE_TEST | 598328 | VOICE |
WEATHER_GNL | 598330 | WEATHER |
WEATHER_GNL_TEST | 598332 | WEATHER |
WEATHER_PS | 598338 | WEATHER |
WEATHER_PS_TEST | 598339 | WEATHER |
WS_LEARNING_ENGLISH | 598340 | WS_LEARNING_ENGLISH |
WS_LEARNING_ENGLISH_TEST | 598341 | WS_LEARNING_ENGLISH |
WS_NEWS_LANGUAGES | 598342 | BBC_WORLD_NEWS |
WS_NEWS_LANGUAGES_TEST | 598343 | BBC_WORLD_NEWS |
WS_PROGRAMMES | 598344 | PROGRAMMES |
WS_PROGRAMMES_TEST | 598345 | PROGRAMMES |
WS_SYNDICATION_PARTNERS | 598346 | WS_PARTNERS_B2B |
WS_SYNDICATION_PARTNERS_TEST | 598347 | WS_PARTNERS_B2B |
WS_PARTNERS_B2B | 598820 | WS_PARTNERS_B2B |
WS_PARTNERS_B2B_TEST | 598823 | WS_PARTNERS_B2B |
Often the Producer will not be the same as the destination however. For example you might be watching a BBC Three programme on the iPlayer, in which case the Destination will be IPLAYER but the producer would be BBC_THREE. In order to override the default, you can provide a value before your view event:
echo.setProducer(Enums.Producers.SCOTLAND);
echo.viewEvent("candy.kingdom.page", {my_test_property:"my_test_value"});
echo.setProducer(Producer.SCOTLAND)
HashMap<String, String> viewProperties = new HashMap<String, String>();
viewLabels.put("my_test_property", "my_test_value");
echo.viewEvent("candy.kingdom.page", viewProperties);
echo.setProducer(.Scotland)
echo.viewEvent(counterName: "test.page", eventLabels: {"my_test_property": "my_test_value"})
Valid Producer values
A full list of valid Producer values is listed below. The ID value is what you will see transmitted in the request to Piano, as the s2
value:
Producer | Piano Site ID |
---|---|
ACADEMY | 125 |
ACCOUNT | 1 |
AFAAN_OROMOO | 2 |
AFRIQUE | 3 |
AMHARIC | 4 |
ARABIC | 5 |
AUDIENCE_SERVICES | 116 |
AZERI | 6 |
BBC | 7 |
BBC_ALBA | 8 |
BBC_ARCHIVE | 127 |
BBC_ARTS | 9 |
BBC_ASIAN_NETWORK | 10 |
BBC_FOOD | 11 |
BBC_FOUR | 12 |
BBC_HD | 13 |
BBC_MUSIC | 14 |
BBC_NEWS_CHANNEL | 15 |
BBC_ONE | 16 |
BBC_PARLIAMENT_CHANNEL | 17 |
BBC_RADIO | 18 |
BBC_RADIO_1 | 19 |
BBC_RADIO_1XTRA | 20 |
BBC_RADIO_2 | 21 |
BBC_RADIO_3 | 22 |
BBC_RADIO_4 | 23 |
BBC_RADIO_4_EXTRA | 24 |
BBC_RADIO_5_LIVE | 25 |
BBC_RADIO_6_MUSIC | 26 |
BBC_SCOTLAND | 120 |
BBC_SEND | 121 |
BBC_STUDIOS | 128 |
BBC_THREE | 28 |
BBC_TWO | 29 |
BBC_WORLD_NEWS | 30 |
BENGALI | 31 |
BITESIZE | 32 |
BRASIL | 33 |
BRITBOX | 34 |
BRITBOX_AU | 132 |
BURMESE | 35 |
CBBC | 36 |
CBEEBIES | 37 |
CHINESE | 38 |
ENGLISH_REGIONS | 39 |
GAHUZA | 40 |
GATEWAY | 41 |
GNL_AUTOS | 42 |
GNL_CAPITAL | 43 |
GNL_CULTURE | 44 |
GNL_EARTH | 45 |
GNL_FUTURE | 46 |
GNL_HOMEPAGE | 47 |
GNL_STORYWORKS | 48 |
GNL_TRAVEL | 49 |
GUJARATI | 50 |
HAUSA | 51 |
HINDI | 52 |
IGBO | 53 |
INDONESIAN | 54 |
IPLAYER | 55 |
JAPANESE | 56 |
KOREAN | 57 |
KYRGYZ | 58 |
MARATHI | 59 |
MEDIA_ACTION | 60 |
MONITORING | 61 |
MUNDO | 62 |
NEPALI | 63 |
NEWS | 64 |
NEWS_ENGLISH_REGIONS | 108 |
NEWS_LABS | 129 |
NEWS_NORTHERN_IRELAND | 114 |
NEWS_SCOTLAND | 110 |
NEWS_WALES | 112 |
NEWSROUND | 65 |
NORTHERN_IRELAND | 66 |
OTHER | 67 |
OWN_IT | 118 |
PASHTO | 68 |
PERSIAN | 69 |
PIDGIN | 70 |
PROGRAMMES | 71 |
PS_HOMEPAGE | 72 |
PUNJABI | 73 |
RD | 126 |
RECEPTION | 124 |
REEL | 74 |
RUSSIAN | 75 |
S4C | 76 |
SCHOOL_RADIO | 77 |
SCHOOL_REPORT | 78 |
SCOTLAND | 79 |
SEARCH | 80 |
SERBIAN | 81 |
SINHALA | 82 |
SOMALI | 83 |
SOUNDS | 84 |
SPORT | 85 |
SPORT_ENGLISH_REGIONS | 109 |
SPORT_NORTHERN_IRELAND | 115 |
SPORT_SCOTLAND | 111 |
SPORT_WALES | 113 |
SWAHILI | 86 |
TAMIL | 87 |
TASTER | 88 |
TEACH | 119 |
TELUGU | 89 |
THAI | 90 |
TIGRINYA | 91 |
TURKISH | 92 |
UK_CHINA | 93 |
UKRAINIAN | 94 |
URDU | 95 |
UZBEK | 96 |
VIETNAMESE | 97 |
VOICE | 98 |
VOICE_FIRST_FORMATS | 99 |
VOLT | 122 |
WALES | 100 |
WEATHER | 101 |
WEATHER_WATCHERS | 102 |
WEBAPPS | 133 |
WORLD_NEWS_PROGRAMMES | 117 |
WORLD_SERVICE_ENGLISH | 103 |
WORKLIFE | 104 |
WS_LEARNING_ENGLISH | 105 |
WS_PARTNERS_B2B | 106 |
YORUBA | 107 |
Setting producer by String or Masterbrand
As well as the enumerated values demonstrated above, it is possible to set them using a string value (equivalent to the names in the table above) or masterbrand if you are unable to use the enums for some reason:
echo.setProducer("scotland");
// or
echo.setProducerByMasterbrand("bbc_scotland");
echo.viewEvent("candy.kingdom.page", {my_test_property:"my_test_value"});
echo.setProducer("scotland")
// or
echo.setProducerByMasterbrand("bbc_scotland");
HashMap<String, String> viewProperties = new HashMap<String, String>();
viewProperties.put("my_test_property", "my_test_value");
echo.viewEvent("candy.kingdom.page", viewProperties);
echo.setProducer("scotland")
// or
echo.setProducerByMasterbrand("bbc_scotland")
echo.viewEvent(counterName: "test.page", eventLabels: {"my_test_property": "my_test_value"})
Note that masterbrand values need to be translated into a valid producer, so they are not always a one-to-one mapping. A list of producers that masterbrands correspond to can be found on Confluence here
Nations Producer
The nations producer value identifies which nation “owns” the content in question. You can set the nations producer by providing a valid value before a view event (a list of valid nation producer values is provided below):
echo.setNationsProducer(Enums.NationsProducer.SCOTLAND);
echo.viewEvent("candy.kingdom.page", {my_test_property:"my_test_value"});
echo.setNationsProducer(NationsProducer.SCOTLAND)
HashMap<String, String> viewProperties = new HashMap<String, String>();
viewProperties.put("my_test_property", "my_test_value");
echo.viewEvent("candy.kingdom.page", viewProperties);
echo.setNationsProducer(nationsProducer: .Scotland)
echo.viewEvent(counterName: "test.page", eventLabels: {"my_test_property": "my_test_value"})
You can remove the nations producer by providing NONE as the value (this will remove any previously set nations producer from future events):
echo.setNationsProducer(Enums.NationsProducer.NONE);
echo.setNationsProducer(NationsProducer.NONE)
echo.setNationsProducer(nationsProducer: .None)
If you provide an invalid nations producer this will have no effect, except for null
or ""
(if accepted by the platform) which will remove any previously set nations producer.
Valid Nation Producer values
A full list of valid Nations Producer values is listed below.
Nations Producer |
---|
NONE |
ENGLAND |
NORTHERN_IRELAND |
SCOTLAND |
WALES |
Section
The section event property is provided as a way to provide categorisation information about your content.
Section is provided as a single value and subsections should be separated by a double-colon, omitting any parts that you do not wish to provide, eg: section, section::subsection or section::subsection::subsubsection
They should be provided as event properties for every view event:
echo.viewEvent("candy.kingdom.page", {
section: "section::subsection::subsubsection"
});
HashMap<String, String> viewProperties = new HashMap<String, String>();
viewProperties.put("section", "section::subsection::subsubsection");
echo.viewEvent("candy.kingdom.page", viewProperties);
echo.viewEvent(counterName: "candy.kingdom.page", eventLabels: {
"section": "section::subsection::subsubsection",
})
Site variables
Site variables are used as a method of providing further meta data on content view events. There are 9 variables that have been defined across all BBC sites, as well as 10 custom variables that vary by product, though the property provided will be the same.
App Type
and App Name
are provided during the Echo initialisation process and requires no change to your code.
As with Section above, these variables can be provided through the eventProperties
parameter of the view event as follows:
echo.viewEvent("candy.kingdom.page", {
Enums.EchoLabelKeys.CONTENT_ID: "scheme:namespace:authority:identifier",
Enums.EchoLabelKeys.CONTENT_TYPE: "article"
});
HashMap<String, String> viewProperties = new HashMap<String, String>();
viewProperties.put(EchoLabelKeys.CONTENT_ID, "scheme:namespace:authority:identifier");
viewProperties.put(EchoLabelKeys.CONTENT_TYPE, "article");
echo.viewEvent("candy.kingdom.page", viewProperties);
echo.viewEvent(counterName: "candy.kingdom.page", eventLabels: {
EchoLabelKeys.ContentId.rawValue: "scheme:namespace:authority:identifier",
EchoLabelKeys.ContentType.rawValue: "article"
})
or via the addProperties
and addProperty
functions of echo client. Note that properties set this way will persist between view events, and will be overwritten if given again in eventProperties
.
echo.addProperties({
Enums.EchoLabelKeys.CONTENT_ID:"scheme:namespace:authority:identifier",
Enums.EchoLabelKeys.CONTENT_TYPE:"article"
});
HashMap<String, String> viewProperties = new HashMap<String, String>();
viewProperties.put(EchoLabelKeys.CONTENT_ID, "scheme:namespace:authority:identifier");
viewProperties.put(EchoLabelKeys.CONTENT_TYPE, "article");
echo.addProperties(viewProperties);
echo.addProperties(eventLabels: {
EchoLabelKeys.ContentId.rawValue: "scheme:namespace:authority:identifier",
EchoLabelKeys.ContentType.rawValue: "article"
})
What to use for Site variables
Available site variables keys are defined through the EchoLabelKeys
enum. They are:
Custom Variable | Key | Description |
---|---|---|
Content Id | CONTENT_ID | The Content ID is a unique identifier produced by a BBC content management system. <scheme>:<namespace>:<authority>:<identifier> |
Content Type | CONTENT_TYPE | Content Type is used to define the purpose of a the content within a page/screen or response. |
Language | LANGUAGE | Used for tracking content language versions. |
URL | URL | The current page full URL (inc parameters) |
Referrer URL | REFERRER_URL | Return the previous page Request URL |
Page Title | PAGE_TITLE | Human Readable name for the Page. |
App Category | APP_CATEGORY | Field to define a app genre category before the App Name. Prepended to app name in reports |
If you’re unsure of what to use for these values, check the “Global Custom Variables” document on Confluence
Product Custom Variables
Products can assign up to 10 custom variables. These are all assigned with the same property keys, custom_var_1
, custom_var_2
, custom_var_3
through to custom_var_10
(also available through the EchoLabelKeys
enum). For information of what to put in each field for each product, see the “Product Custom Variables” document on confluence
Custom properties
In addition to the above, as part of Piano’s New Data Factory (NDF) they can now accept a greater range of custom properties. It must be noted, Echo Label constants are not available for custom properties and raw string versions must be used. For example, EchoLabelKeys
constants cannot be used, instead a string must be used.
These are set in the same way as the variables mentioned, either by using the addProperty
and addProperties
methods, or by passing them to events using the eventProperties
parameter. They differ because in theory you can use any number of properties with any names you like.
The caveat is they must be registered with Piano before they will be ingested (unregistered properties will be ignored), and reporting on these properties will only be possible via the NDF. A list of existing custom properties can be found here. Additionally, you can request a new custom property or event here.
Property name | Alternative Method/s |
---|---|
page | pageView OR setCounterName |
echo.addProperty("property_1", "mypropertyvalue");
echo.addProperties({"property_2": "mypropertyvalue2", "property_3": "mypropertyvalue3"});
echo.removeProperties(["property_1", "property_3"]);
echo.addProperty("property_1", "mypropertyvalue");
HashMap<String, String> propertiesToAdd = new HashMap<String, String>();
propertiesToAdd.put("property_2", "mypropertyvalue2");
propertiesToAdd.put("property_3", "mypropertyvalue3");
echo.addProperties(propertiesToAdd);
HashSet<String> propertiesToRemove = new HashSet<String>();
propertiesToRemove.add("property_1");
propertiesToRemove.add("property_3");
echo.removeProperties(propertiesToRemove);
// Expects a dictionary
echo.addProperties({"property_1": "mypropertyvalue1", "property_2": "mypropertyvalue2"})
// Expects an array
echo.removeProperties(["property_1", "property_2"])
Handling DeepLinks
From Echo iOS 7.4.0 and Echo Android 20.2.0, when a deeplink is provided to addProperties
or viewEvent
methods, i.e. link_location
property is set, it will be separated out into props that it contains. This is not the case if provided to any other method.
For example, props from link_location = CPG=cross-promotion$DCV=display
will be separated into src_campaign = cross-promotion
and src_medium = display
.
In order to constuct a link_location
property, you must use the following link_location
to src
value map:
link_location value | src value |
---|---|
Mechanism (MEC) | src_link_type |
Directive (DCV) | src_medium |
Entity (ENT) | src_brand |
Playback Type (PBK) | src_format |
Origin (ORG) | src_link_origin |
Partner (PTR) | src_ptr_name |
Campaign Value (CPG) | src_campaign |
Autoverify (ATV) | src_autoverify |
URI Location (ULT) | src_uri_location |
Campaign tracking
Marketing campaign attribution can be tracked on mobile by setting the following event property:
HashMap<String, String> viewProperties = new HashMap<String, String>();
viewProperties.put(EchoLabelKeys.CAMPAIGN, "CS1-14-[Sounds~Installation Campaign][Facebook][]-[]");
echo.viewEvent("candy.kingdom.page", viewProperties);
echo.viewEvent(counterName: "candy.kingdom.page", eventLabels: {
EchoLabelKeys.Campaign.rawValue: "CS1-14-[Sounds~Installation Campaign][Facebook][]-[]"
})
Campaigns on the web can be tracked using the addProperties
function:
var campaignProperties = {};
campaignProperties[Enums.EchoLabelKeys.CHANNEL] = 'channel';
campaignProperties[Enums.EchoLabelKeys.MEDIUM] = 'medium';
campaignProperties[Enums.EchoLabelKeys.CAMPAIGN] = 'campaign';
campaignProperties[Enums.EchoLabelKeys.CAMPAIGN_GROUP] = 'campaign_group';
campaignProperties[Enums.EchoLabelKeys.VENDOR] = 'vendor';
campaignProperties[Enums.EchoLabelKeys.CREATION] = 'creation';
campaignProperties[Enums.EchoLabelKeys.AFFILIATE_TYPE] = 'aff_type';
echo.addProperties(campaignProperties);
AV reporting
This works in essentially the same way as before, with a couple of exceptions:
Media producer
You can specify a different producer for a media item than the page it is hosted on (to represent for example BBC Three content on the iPlayer website, or BBC Sport content on the BBC News website):
myMedia.setProducer(Enums.Producer.BBC_THREE);
myMedia.setProducer(Producer.BBC_THREE);
myMedia.producer = .BBCThree
If no producer is set, then no producer will be applied. It will not inherit from the containing page’s producer.
Setting media producer by String or Masterbrand
As with page producers, media producers can be set using string values and also, as in the example below, masterbrands:
myMedia.setProducer("bbc_radio_1xtra");
myMedia.setProducerByMasterbrand("bbc_1xtra");
myMedia.setProducer("bbc_radio_1xtra");
myMedia.media.setProducerByMasterbrand("bbc_1xtra");
myMedia.producerName = "bbc_radio_1xtra"
myMedia.setProducerByMasterbrand("bbc_1xtra")
A list of producers that masterbrands correspond to can be found on Confluence here
Media themes
Due to how Piano records media information, their media themes (similar to section for page content) are used to allow us to supply all the necessary information.
This is largely the same as before, but additional guidance on these is on the AV Reporting page documentation. Note that some new properties are available such as name, playlist ID and streaming device ID.
User Action Events
Custom Events
To send a Custom Event, use Echo’s userActionEvent
method. You must supply an actionType
(event_category) and actionName
(event_action) in order to set a name for your custom event. This will appear in the format, event_category.event_action
.
You can provide custom properties in the eventProperties
parameter. For guidance on Custom Properties, please see the section above.
The eventProperties
parameter can be supplied as a JSON object (JS), or as a HashMap (Android) / Dictionary (iOS). See the following snippets for usage and output.
// Method signature
echo.userActionEvent(actionType, actionName, eventProperties);
// Send a user action event - JSON:
echo.userActionEvent("player", "pause", {"{\"test_property_user_action\":\"user_action_prop\",\"additional_property\":\"additional_value\",\"third_deeply_nested_prop_with_a_value\":\"third_prop_value\"}"});
// events array sent - JSON:
"events": [
{
"name": "player.pause",
"data": {
"name": "echo.test.page",
"level2": 7,
"testcookiedomain": "bbc.co.uk",
"test": {
"property": {
"user": {
"action": "user_action_prop"
}
}
},
"additional": {
"property": "additional_value"
},
"third": {
"deeply": {
"nested": {
"prop": {
"with": {
"a": {
"value": "third_prop_value"
}
}
}
}
}
},
"echo": {
"event": "userAct"
},
"event": {
"action": "pause",
"category": "player"
},
"user": null
}
}
],
// Method signature
public void userActionEvent(String actionType, String actionName,
HashMap<String, String> eventLabels)
// Send a user action event - HashMap:
HashMap<String, String> exampleEventProperties = new HashMap<>();
exampleEventProperties.put(EchoLabelKeys.USER_ACTION_TYPE, "player");
exampleEventProperties.put(EchoLabelKeys.USER_ACTION_NAME, "pause");
exampleEventProperties.put("test_property_user_action", "user_action_prop");
exampleEventProperties.put("additional_property", "additional_value");
exampleEventProperties.put("third_deeply_nested_prop_with_a_value", "third_prop_value");
userActionEvent("player", "pause", exampleEventProperties);
// events array sent - JSON:
"events": [
{
"name": "player.pause",
"data": {
"ml": {
"version": "echo_android-19.7.0"
},
"event": {
"action": "pause",
"category": "player"
},
"test": {
"property": {
"user": {
"action": "user_action_prop"
}
}
},
"additional": {
"property": "additional_value"
},
"echo": {
"event": "userAct"
},
"app": {
"name": "echo-android-test",
"type": "mobile-app"
},
"third": {
"deeply": {
"nested": {
"prop": {
"with": {
"a": {
"value": "third_prop_value"
}
}
}
}
}
},
}
}
],
// Method signature
func userActionEvent(actionType: String, actionName: String, eventProperties: [String: String]?)
// Send a user action event - Dictionary:
let exampleEventProperties = ["test_property_user_action": "user_action_prop",
"additional_property": "additional_value",
"third_deeply_nested_prop_with_a_value": "third_prop_value"]
userActionEvent(actionType: "player", actionName: "pause", eventProperties: exampleEventProperties)
// events array sent - JSON:
"events": [
{
"name": "player.pause",
"data": {
"test": {
"property": {
"user": {
"action": "user_action_prop"
}
}
},
"app": {
"type": "mobile-app",
"name": "ios-test-app"
},
"event": {
"category": "player",
"action": "pause"
},
"third": {
"deeply": {
"nested": {
"prop": {
"with": {
"a": {
"value": "third_prop_value"
}
}
}
}
}
},
"additional": {
"property": "additional_value"
},
"ml": {
"version": "echo_ios_swift-6.8.0"
},
"echo": {
"event": "userAct"
}
}
}
],
Publisher Events
Existing Publisher Events will continue to work as before. In order to send a Publisher Event, you must set at least one of the following Echo Properties:
Piano publisher name | BBC name | Echo property | Default values | Notes |
---|---|---|---|---|
variant | User Experience | personalisation | n/a | |
format | Metadata | metadata | n/a | |
advertiserId | Source | source | n/a | |
url | Result | result | n/a | |
??? | ??? | is_background | n/a |
Note the is_background
property, which will determine whether this event was prompted by user interaction (where it should be false
), or by application events that occur independently of user interaction (eg, errors, status updates, where it should be true
). This determines whether they are considered to be “clicks” or “impressions” by Piano. This will default to false
so that if you don’t specify, they will be considered “clicks”. In the event no publisher values are set, you can set is_background
to false
in order to send a Publisher Event.
For setting properties in the userActionEvent
method, guidance can be found here on what to set now, as there are restrictions on what will be shown in the reporting interface.
Piano’s “Publisher” ad-tracking feature is being used for this purpose. The property names to use for each property are outlined below:
Piano publisher name | BBC name | Echo property | Default values | Notes |
---|---|---|---|---|
campaignId | Container | container | page (for JS), application (for mobile) | |
creation | Attribute | n/a | n/a | This is a concatenation of the existing actionName and actionType parameters for the method |
variant | User Experience | personalisation | n/a | |
format | Metadata | metadata | n/a | |
generalPlacement | Placement | n/a | Name of the current page/screen | This is automatically filled in by Echo |
detailedPlacement | Account | n/a | The current user’s HID (if signed in and available) | This is automatically filled in by Echo — a zero value indicates signed out |
advertiserId | Source | source | n/a | |
url | Result | result | n/a |
Example calls, and the resulting values sent to ATI, would therefore look like this (note the difference in the parameter names - atc
represents a click and ati
an impression):
// Method signature
echo.userActionEvent(actionType, actionName, eventProperties);
// Send a user action event:
echo.userActionEvent("auth", "signIn", {"container":"page", "personalisation":"personalisation values", "metadata":"metadata values", "source":"content ID", "result":"http://www.example.com"});
// atc parameter sent:
// "atc": "PUB-[page]-[signIn~auth]-[personalisation values]-[metadata values]-[countername.page]-[user HID]-[content ID]-[http://www.example.com]"
// Send a background event:
echo.userActionEvent("error", "mediaLoad", {"is_background":"true", "container":"page", "personalisation":"personalisation values", "metadata":"metadata values", "source":"content ID", "result":"http://www.example.com"});
// Piano parameter sent:
// "ati": "PUB-[page]-[mediaLoad~error]-[personalisation values]-[metadata values]-[countername.page]-[user HID]-[content ID]-[http://www.example.com]"
Note that if you are interested in click-through-rate, in order for that to be calculated, both the impression and the click need to have the same Container/Attribute values.
Custom Event or Publisher Event, how can I tell?
It is possible to examine ATI/Piano requests using Charles or a similar proxy. Capture an event and inspect the events
array. Within events
exists a data
object, within which all Publisher/Custom data is set.
Publisher events will have either publisher.display
or publisher.click
as the name
, whereas a Custom Event’s name
will be set as mentioned above.
Additionally, all Publisher events will contain an onsitead
within the data
object. See the following snippet for examples.
// Custom Event - example events array
"events": [
{
"name": "user.action.one.test", <----- Custom Event name built by provided actionType and actionName
"data": { <----- Data should contain all of your Custom Properties
"app": {
"name": "echo-integration-test",
"type": "mobile-app"
},
"ml": {
"version": "echo_ios_swift-6.7.0"
},
"echo": {
"event": "userAct"
},
"event": {
"action": "test",
"category": "user.action.one"
}
}
}
]
// Publisher Event - example events array
"events": [
{
"name": "publisher.display", <----- either publisher.display or publisher.click
"data": {
"onsitead": { <----- every Publisher Event will contain this object
"format": "",
"detailedplacement": "test--12_!string",
"variant": "",
"campaign": "Application",
"generalplacement": "",
"creation": "first_install~echo_device_id",
"advertiser": "",
"url": "unknown"
}
}
}
],
Cookies
Piano sets a cookie called atuserid
to keep track of a browser across multiple pages. Echo will set the domain for this cookie to be .bbc.co.uk
, .bbc.com
, or .britbox.com
depending on the domain of the current page. This ensures that a single user journey can be measured across the various subdomains (Piano’s default behaviour would create a different cookie per subdomain).
Only if you are using Echo outside of the bbc.co.uk, bbc.com, or britbox.com domains, you can enable the following config option to revert to Piano’s default behaviour and use the full domain of the page (otherwise it will be set on .bbc.co.uk
):
var conf = { };
conf[Echo.ConfigKeys.ATI_USE_DEFAULT_COOKIE_DOMAIN] = true;
// Instantiate EchoClient
var echo = new EchoClient('MyApp', Enums.ApplicationType.WEB, conf);
This option is available from version 12.13.0 onwards.