Search code examples
phpgoogle-analytics

Sending GA4 event from Server Side PHP not working


I have a form completion event I want to send from the server side so I can validate and filter out spam first. It works fine when send through javascript.

const measurement_id = `G-XXXXXXXXXX`;
const api_secret = `api_secret_key`;

fetch(`https://www.google-analytics.com/mp/collect?measurement_id=${measurement_id}&api_secret=${api_secret}`, {
  method: "POST",
  body: JSON.stringify({
    client_id: '1552776741.1677766660',
    events: [{
      name: 'form_submission',
      params: {'form_name':'Send A Message',
      'is_lead':'Lead+Submission',
      'submission_url':'Unknown'},
    }]
  })
});

When I go to send it with PHP instead, it never makes it to GA4 but also does not return any kind of error message.

$measurement_id = 'G-XXXXXXXXXX';
$api_secret = 'api_secret_key';
$url = "https://www.google-analytics.com/mp/collect?measurement_id=" . $measurement_id . "&api_secret=" . $api_secret;

$data = array(
  'client_id' => '1552776741.1677766660', 
  'events' => array(
    'name' => 'form_submission', 
    'params' => array(
      'form_name' => 'Send A Message 2', 
      'is_lead' => 'Non-Lead Submission', 
      'submission_url' => 'Unknown'
    )
  )
);

$options = array(
  'http' => array(
    'header'  => "Content-type: text/plain;charset=UTF-8",
    'method'  => 'POST',
    'content' => http_build_query($data)
  )
);
$context  = stream_context_create($options);
$resp = file_get_contents($url, false, $context);
echo $resp;

Any insight into how to get this to process would be greatly appreciated.


Solution

  • There are a few issues with the PHP code that could be preventing the event from being sent to GA4:

    1. The events array should contain an object with name and params properties, not just an array. This means you need to wrap the name and params in an object like this:
    'events' => array(
        array(
          'name' => 'form_submission', 
          'params' => array(
            'form_name' => 'Send A Message 2', 
            'is_lead' => 'Non-Lead Submission', 
            'submission_url' => 'Unknown'
          )
        )
      )
    
    1. The Content-type header should be set to application/json since the body is being sent as JSON.

    2. You're using http_build_query() to encode the data, but it should be encoded as JSON instead. You can use json_encode() to do this:

    $options = array(
      'http' => array(
        'header'  => "Content-type: application/json",
        'method'  => 'POST',
        'content' => json_encode($data)
      )
    );
    

    Here's the corrected code:

    $measurement_id = 'G-XXXXXXXXXX';
    $api_secret = 'api_secret_key';
    $url = "https://www.google-analytics.com/mp/collect?measurement_id=" . $measurement_id . "&api_secret=" . $api_secret;
    
    $data = array(
      'client_id' => '1552776741.1677766660', 
      'events' => array(
        array(
          'name' => 'form_submission', 
          'params' => array(
            'form_name' => 'Send A Message 2', 
            'is_lead' => 'Non-Lead Submission', 
            'submission_url' => 'Unknown'
          )
        )
      )
    );
    
    $options = array(
      'http' => array(
        'header'  => "Content-type: application/json",
        'method'  => 'POST',
        'content' => json_encode($data)
      )
    );
    $context  = stream_context_create($options);
    $resp = file_get_contents($url, false, $context);
    echo $resp;
    

    Make sure to replace G-XXXXXXXXXX with your actual measurement ID and api_secret_key with your actual API secret key.