Link Search Menu Expand Document

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.

If you are using Echo in a page where Orbit is present, you should instead provide these values to Orbit so that they can be reused more easily by the various modules that need them. More information to follow on how this is configured...

Table of contents

  1. Enabling Piano reporting
  2. Destination
    1. Maintaining the Account User Journey
  3. Producer
    1. Valid Producer values
    2. Setting producer by String or Masterbrand
  4. Nations Producer
    1. Valid Nation Producer values
  5. Section
  6. Site variables
    1. What to use for Site variables
    2. Product Custom Variables
  7. Custom properties
  8. Handling DeepLinks
  9. Campaign tracking
  10. AV reporting
    1. Media producer
    2. Setting media producer by String or Masterbrand
    3. Media themes
  11. User Action Events
    1. Custom Events
    2. Publisher Events
    3. Custom Event or Publisher Event, how can I tell?
  12. 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

Piano has transitioned from their current data factory (referred to as CDF) to a new data factory (NDF). This provides a far greater range of events and data that can be collected and exposed. Now that Data Flow 2 (DF2) is live Echo will try to provide access to these new features in a logical and backwards compatible way. Check out the custom events section below!

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.

The following custom properties are restricted and will not be sent if you try and set them. We have provided the alternative methods that should be used.
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"])
  

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);
  
The campaign, channel, and medium properties are all required and if you do not provide these the campaign properties will not be added.

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.