This function helps take HTTP events and rearranges its structure so it will work in a MP measurement protocol hit. This enables HTTP events from say Pub/Sub to be translated into MP hits.

mp_parse_json(
  json,
  name_f,
  params_f = NULL,
  items_f = NULL,
  client_id_f = NULL,
  user_id_f = NULL,
  user_properties_f = NULL
)

mp_parse_gtm(json)

mp_pubsub(pubsub_body)

Arguments

json

The location of a json file or a json string or an R list that has been parsed from json via jsonlite::fromJSON

name_f

The function that extracts the event name out of json

params_f

An optional function that extracts parameters for the event from json

items_f

An optional function that extracts e-commerce items from json. Must return a mp_event_item object. you may not need this if the params_f includes parsing of e-commerce items

client_id_f

An optional function to extract the client.id. You will need to supply cid though if using downstream in mp_send so it usually is necessary

user_id_f

Optionally include a function that will parse out user_id

user_properties_f

Optionally include a function that will parse out user properties

pubsub_body

The req$postBody of a plumber request

Value

An mp_parse_json object that is a list of an mp_event object, and user fields including client.id, user.id and user properties The Pub/Sub message "data" attribute unencoded into a json string

Details

The passed in functions should return NULL if they don't find any entries

Examples


demo_json <- system.file("example", "pubsub-ga4.json", package = "measurementProtocol")
demo_list <- jsonlite::fromJSON(demo_json)


# extract the event_name
name_f <- function(x) x[["event_name"]]

# extract client_id
client_id_f <- function(x) x[["client_id"]]

# extract user_id
user_id_f <- function(x) x[["user_id"]]

# simple event
mp_parse_json(demo_list,
              name_f,
              client_id_f = client_id_f,
              user_id_f = user_id_f)
#>  2022-02-08 08:52:04 > Received JSON: {
#>   "x-ga-protocol_version": "2",
#>   "x-ga-measurement_id": "G-43MDXK6CLZ",
#>   "x-ga-gtm_version": "2reba1",
#>   "x-ga-page_id": 1331862949,
#>   "screen_resolution": "1280x720",
#>   "language": "en-us",
#>   "client_id": "106601226.163731234",
#>   "x-ga-request_count": 1,
#>   "page_location": "https://code.markedmondson.me/shiny-cloudrun/",
#>   "page_referrer": "https://www.google.com/",
#>   "page_title": "Shiny on Google Cloud Run - Scale-to-Zero R Web Apps · Mark Edmondson",
#>   "ga_session_id": "1637391234",
#>   "ga_session_number": 3,
#>   "x-ga-mp2-seg": "0",
#>   "event_name": "page_view",
#>   "x-ga-system_properties": {
#>     "ss": "1"
#>   },
#>   "debug_mode": "true",
#>   "ip_override": "123.456.789.111",
#>   "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
#>   "x-ga-gcs-origin": "not-specified",
#>   "user_id": "random-user"
#> }
#> $raw
#> $raw$`x-ga-protocol_version`
#> [1] "2"
#> 
#> $raw$`x-ga-measurement_id`
#> [1] "G-43MDXK6CLZ"
#> 
#> $raw$`x-ga-gtm_version`
#> [1] "2reba1"
#> 
#> $raw$`x-ga-page_id`
#> [1] 1331862949
#> 
#> $raw$screen_resolution
#> [1] "1280x720"
#> 
#> $raw$language
#> [1] "en-us"
#> 
#> $raw$client_id
#> [1] "106601226.163731234"
#> 
#> $raw$`x-ga-request_count`
#> [1] 1
#> 
#> $raw$page_location
#> [1] "https://code.markedmondson.me/shiny-cloudrun/"
#> 
#> $raw$page_referrer
#> [1] "https://www.google.com/"
#> 
#> $raw$page_title
#> [1] "Shiny on Google Cloud Run - Scale-to-Zero R Web Apps · Mark Edmondson"
#> 
#> $raw$ga_session_id
#> [1] "1637391234"
#> 
#> $raw$ga_session_number
#> [1] 3
#> 
#> $raw$`x-ga-mp2-seg`
#> [1] "0"
#> 
#> $raw$event_name
#> [1] "page_view"
#> 
#> $raw$`x-ga-system_properties`
#> $raw$`x-ga-system_properties`$ss
#> [1] "1"
#> 
#> 
#> $raw$debug_mode
#> [1] "true"
#> 
#> $raw$ip_override
#> [1] "123.456.789.111"
#> 
#> $raw$user_agent
#> [1] "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
#> 
#> $raw$`x-ga-gcs-origin`
#> [1] "not-specified"
#> 
#> $raw$user_id
#> [1] "random-user"
#> 
#> 
#> $mp_event
#> 
#> ==GA4 MP Event
#> {
#>   "name": "page_view"
#> } 
#> 
#> $user
#> $user$client_id
#> [1] "106601226.163731234"
#> 
#> $user$user_id
#> [1] "random-user"
#> 
#> $user$user_properties
#> NULL
#> 
#> 
#> attr(,"class")
#> [1] "mp_parse_json" "list"         

# params could be assumed to be everything not a event_name of client_id
# also not allowed any starting with reserved 'ga_'
params_f <- function(x){
  x_names <- names(x)[grepl("^x-", names(x))]
  ga_names <- names(x)[grepl("^ga_", names(x))]
  x[setdiff(names(x), c("client_id","user_id" ,"event_name", x_names, ga_names))]
  }

# parse including params (could include items as well)
parsed_event <- mp_parse_json(demo_list,
                              name_f,
                              params_f = params_f,
                              client_id_f = client_id_f,
                              user_id_f = user_id_f)
#>  2022-02-08 08:52:04 > Received JSON: {
#>   "x-ga-protocol_version": "2",
#>   "x-ga-measurement_id": "G-43MDXK6CLZ",
#>   "x-ga-gtm_version": "2reba1",
#>   "x-ga-page_id": 1331862949,
#>   "screen_resolution": "1280x720",
#>   "language": "en-us",
#>   "client_id": "106601226.163731234",
#>   "x-ga-request_count": 1,
#>   "page_location": "https://code.markedmondson.me/shiny-cloudrun/",
#>   "page_referrer": "https://www.google.com/",
#>   "page_title": "Shiny on Google Cloud Run - Scale-to-Zero R Web Apps · Mark Edmondson",
#>   "ga_session_id": "1637391234",
#>   "ga_session_number": 3,
#>   "x-ga-mp2-seg": "0",
#>   "event_name": "page_view",
#>   "x-ga-system_properties": {
#>     "ss": "1"
#>   },
#>   "debug_mode": "true",
#>   "ip_override": "123.456.789.111",
#>   "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
#>   "x-ga-gcs-origin": "not-specified",
#>   "user_id": "random-user"
#> }
parsed_event
#> $raw
#> $raw$`x-ga-protocol_version`
#> [1] "2"
#> 
#> $raw$`x-ga-measurement_id`
#> [1] "G-43MDXK6CLZ"
#> 
#> $raw$`x-ga-gtm_version`
#> [1] "2reba1"
#> 
#> $raw$`x-ga-page_id`
#> [1] 1331862949
#> 
#> $raw$screen_resolution
#> [1] "1280x720"
#> 
#> $raw$language
#> [1] "en-us"
#> 
#> $raw$client_id
#> [1] "106601226.163731234"
#> 
#> $raw$`x-ga-request_count`
#> [1] 1
#> 
#> $raw$page_location
#> [1] "https://code.markedmondson.me/shiny-cloudrun/"
#> 
#> $raw$page_referrer
#> [1] "https://www.google.com/"
#> 
#> $raw$page_title
#> [1] "Shiny on Google Cloud Run - Scale-to-Zero R Web Apps · Mark Edmondson"
#> 
#> $raw$ga_session_id
#> [1] "1637391234"
#> 
#> $raw$ga_session_number
#> [1] 3
#> 
#> $raw$`x-ga-mp2-seg`
#> [1] "0"
#> 
#> $raw$event_name
#> [1] "page_view"
#> 
#> $raw$`x-ga-system_properties`
#> $raw$`x-ga-system_properties`$ss
#> [1] "1"
#> 
#> 
#> $raw$debug_mode
#> [1] "true"
#> 
#> $raw$ip_override
#> [1] "123.456.789.111"
#> 
#> $raw$user_agent
#> [1] "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
#> 
#> $raw$`x-ga-gcs-origin`
#> [1] "not-specified"
#> 
#> $raw$user_id
#> [1] "random-user"
#> 
#> 
#> $mp_event
#> 
#> ==GA4 MP Event
#> {
#>   "name": "page_view",
#>   "params": {
#>     "screen_resolution": "1280x720",
#>     "language": "en-us",
#>     "page_location": "https://code.markedmondson.me/shiny-cloudrun/",
#>     "page_referrer": "https://www.google.com/",
#>     "page_title": "Shiny on Google Cloud Run - Scale-to-Zero R Web Apps · Mark Edmondson",
#>     "debug_mode": "true",
#>     "ip_override": "123.456.789.111",
#>     "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
#>   }
#> } 
#> 
#> $user
#> $user$client_id
#> [1] "106601226.163731234"
#> 
#> $user$user_id
#> [1] "random-user"
#> 
#> $user$user_properties
#> NULL
#> 
#> 
#> attr(,"class")
#> [1] "mp_parse_json" "list"         

# sending to a debug endpoint
# preferably set this in .Renviron
Sys.setenv(MP_SECRET="MY_SECRET")

# replace with your GA4 settings
my_measurement_id <- "G-1234"
my_connection <- mp_connection(my_measurement_id)
mp_send(parsed_event$mp_event,
        client_id = parsed_event$user$client_id,
        user_id = parsed_event$user$user_id,
        user_properties = parsed_event$user$user_properties,
        connection = my_connection,
        debug_call = TRUE)
#>  2022-02-08 08:52:04 > MP Request: https://www.google-analytics.com/debug/mp/collect?measurement_id=G-1234&api_secret=MY_SECRET 
#>  {
#>   "client_id": "106601226.163731234",
#>   "user_id": "random-user",
#>   "non_personalized_ads": true,
#>   "events": [
#>     {
#>       "name": "page_view",
#>       "params": {
#>         "screen_resolution": "1280x720",
#>         "language": "en-us",
#>         "page_location": "https://code.markedmondson.me/shiny-cloudrun/",
#>         "page_referrer": "https://www.google.com/",
#>         "page_title": "Shiny on Google Cloud Run - Scale-to-Zero R Web Apps · Mark Edmondson",
#>         "debug_mode": "true",
#>         "ip_override": "123.456.789.111",
#>         "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
#>       }
#>     }
#>   ]
#> }
#> 
#>  2022-02-08 08:52:04 > Response:  200
#>  2022-02-08 08:52:04 > No validation messages found
#> [1] TRUE



# mp_parse_gtm internally uses functions demonstrated with mp_parse_json
pubsub_event <- mp_parse_gtm(demo_json)
#>  2022-02-08 08:52:04 > Received JSON: {
#>   "x-ga-protocol_version": "2",
#>   "x-ga-measurement_id": "G-43MDXK6CLZ",
#>   "x-ga-gtm_version": "2reba1",
#>   "x-ga-page_id": 1331862949,
#>   "screen_resolution": "1280x720",
#>   "language": "en-us",
#>   "client_id": "106601226.163731234",
#>   "x-ga-request_count": 1,
#>   "page_location": "https://code.markedmondson.me/shiny-cloudrun/",
#>   "page_referrer": "https://www.google.com/",
#>   "page_title": "Shiny on Google Cloud Run - Scale-to-Zero R Web Apps · Mark Edmondson",
#>   "ga_session_id": "1637391234",
#>   "ga_session_number": 3,
#>   "x-ga-mp2-seg": "0",
#>   "event_name": "page_view",
#>   "x-ga-system_properties": {
#>     "ss": "1"
#>   },
#>   "debug_mode": "true",
#>   "ip_override": "123.456.789.111",
#>   "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
#>   "x-ga-gcs-origin": "not-specified",
#>   "user_id": "random-user"
#> }

mp_send(pubsub_event$mp_event,
        client_id = pubsub_event$user$client_id,
        user_id = pubsub_event$user$user_id,
        user_properties = pubsub_event$user$user_properties,
        connection = my_connection,
        debug_call = TRUE)
#>  2022-02-08 08:52:04 > MP Request: https://www.google-analytics.com/debug/mp/collect?measurement_id=G-1234&api_secret=MY_SECRET 
#>  {
#>   "client_id": "106601226.163731234",
#>   "user_id": "random-user",
#>   "non_personalized_ads": true,
#>   "events": [
#>     {
#>       "name": "page_view",
#>       "params": {
#>         "screen_resolution": "1280x720",
#>         "language": "en-us",
#>         "page_location": "https://code.markedmondson.me/shiny-cloudrun/",
#>         "page_referrer": "https://www.google.com/",
#>         "page_title": "Shiny on Google Cloud Run - Scale-to-Zero R Web Apps · Mark Edmondson",
#>         "debug_mode": "true",
#>         "ip_override": "123.456.789.111",
#>         "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
#>       }
#>     }
#>   ]
#> }
#> 
#>  2022-02-08 08:52:04 > Response:  200
#>  2022-02-08 08:52:04 > No validation messages found
#> [1] TRUE

if (FALSE) {

#* Send forward a measurement protocol hit
#* @post /gtm
#* @serializer unboxedJSON
#* @parser json
function(req, res, ga_id) {

  pubsub_data <- mp_pubsub_parse(req$postBody)

  parsed <- mp_parse_gtm(pubsub_data)

  my_connection <- mp_connection(ga_id)

  mp_send(parsed$mp_event,
          client_id = parsed$user$client_id,
          user_id = parsed$user$user_id,
          user_properties = parsed$user$user_properties,
          connection = my_connection)

  "OK"
  }


}