send a pageview event via Measurement Protocol to a GA4 property
Asked Answered
F

1

11

How can I send a pageview event via Measurement Protocol to a GA4 property with PHP?

This is how I'm doing, but inside my Google Analytics 4 property I can't see any traffic.

$data = array(
    'api_secret' => 'XXXX-YYYYY',
    'measurement_id' => 'G-12345678',
    'client_id' => gen_uuid(), // generates a random id
    'events' => array(
      'name' => 'page_view',
      'params' => array(),
    )
);

$url = 'https://www.google-analytics.com/mp/collect';
$content = http_build_query($data);
$content = utf8_encode($content);

$ch = curl_init();
curl_setopt($ch,CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_HTTPHEADER,array('Content-type: application/x-www-form-urlencoded'));
curl_setopt($ch,CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
curl_setopt($ch,CURLOPT_POST, TRUE);
curl_setopt($ch,CURLOPT_POSTFIELDS, $content);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);
curl_close($ch);
Fulminate answered 21/3, 2022 at 13:12 Comment(1)
Try setting your content type to Content-Type: application/json as per spec developers.google.com/analytics/devguides/collection/protocol/…Treaty
S
12

I'm working on registering pageviews to track API usage right now, here's what I've found:

XTOTHEL is right about setting the content type to content/json above. In addition to specifying the content type you also have to send JSON data as the CURLOPT_POSTFIELDS data.

Also per their specification the api_secret and measurement_id need to be part of the URI: https://developers.google.com/analytics/devguides/collection/protocol/ga4/sending-events?client_type=gtag#required_parameters

Lastly, you can use debug mode to validate your responses and figure out what's going on now by simply changing the URL to google-analytics.com/debug/mp/collect

Here's the code I'm working with right now:

//retrieve or generate GA tracking id
            if (empty($_COOKIE['_cid'])) {
                setcookie('_cid', vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex(random_bytes(16)), 4)));
            }
            $data = '{"client_id":"'.$_COOKIE['_cid'].'","events":[{"name":"load_endpoint","params":{"page_location":"'.$request->fullUrl().'"}}]}';
            echo '<pre>';
            print_r($data);

            $measurement_id = 'G-xxxxx';
            $api_secret = 'xxxx';
            $url = 'https://www.google-analytics.com/debug/mp/collect?api_secret='.$api_secret.'&measurement_id='.$measurement_id;
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            $response = curl_exec($ch);
            curl_close($ch);
            echo $response;

This works to a certain extent. Currently it's registering the page view as a custom event instead of an actual pageview though. I'm still trying to figure out how to get them to come through as page views.

Follow up After a little more debugging I figured out page views are actually working, they just weren't showing up in some of the views. The fix for that was to add page_title into the params:

$data = '
{
  "client_id": "'.$_COOKIE['_cid'].'",
  "events": [
    {
      "name": "page_view",
      "params": {
        "page_location": "'.$request->fullUrl().'",
        "page_title": "'.$request->path().'"
      }
    }
  ]
}
';

A few extra notes for whoever comes next:

  • Debug mode did return some useful validation errors for invalid top-level parameters (client_id, events) - but it didn't return errors for anything inside of the "params" for events. IE - i put "page_asdtitle" instead of "page_title" and it accepted it just fine.
  • None of the tests I sent through actually showed up in the debug panel while using debug mode. I suspect this is because of the data propagation delay, it's probably not loading realtime data.
  • Using a JSON validator can help. Make sure you use objects and arrays where GA tells you to.
  • If you get stuck figuring out why your PHP code doesn't work, write the code as a browser event in JavaScript and run it in your browser. There's tons of examples on how to do that. From there, you can use Dev Tools -> Network to inspect the request. If you right click on the google analytics request to the 'collect' endpoint you'll see an option to Copy Request as CURL. Put that into a text editor and compare it to what your PHP code is sending.
  • To ACTUALLY test this without the massive propagation delay you can login to Google Analytics, go to Reports -> Realtime, and you should see your data show up within 30-60 seconds if it's working. Realtime data will NOT show up if you're using the /debug/ endpoint though.
Saltire answered 24/5, 2022 at 19:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.