Learn business growth with Google Analytics 4 Forums Google Analytics 4 Troubleshooting 404 Error when Implementing GA4 in ColdFusion without Client Library

  • Troubleshooting 404 Error when Implementing GA4 in ColdFusion without Client Library

    Posted by Henry on 1 December 2022 at 2:05 pm

    Hey there, I’m working with ColdFusion and trying to switch our code to use data from GA4 instead of UA. Problem is, I can’t figure out how to give you a simplified example without sharing sensitive info.

    Here’s what my JSON looks like:

    {"DATERANGES":[{"endDate":"2023-02-20","startDate":"2023-01-01"}],"METRICS":[{"name":"activeUsers"}],"DIMENSIONS":[{"name":"country"}]}

    I’m trying to POST this:

    <cfhttp url="https://analyticsdata.googleapis.com/v1beta/properties/XXXXX:runReport" method="post" timeout="15">
        <cfhttpparam type="header" name="Authorization" value="Bearer #access_token#">
        <cfhttpparam type="header" name="Content-type" value="application/json">
        <cfhttpparam type="formfield" name="reportRequests" value="#jsonText#">
    </cfhttp>`

    To get my access_token, I’m posting to https://accounts.google.com/o/oauth2/token like this:

    <cfhttp method="post" url="https://accounts.google.com/o/oauth2/token" Result="call2data">
        <cfhttpparam type="formfield" name="refresh_token" value="#get_token.refresh_token#">
        <cfhttpparam type="formfield" name="client_id" value="#oauth_client_id#">
        <cfhttpparam type="formfield" name="client_secret" value="#oauth_client_secret#">
        <cfhttpparam type="formfield" name="grant_type" value="refresh_token">
    </cfhttp>

    The code to get a new access_token seems to be working fine. But when I send the POST request, I get a 404 error with this message: “The requested URL /v1beta/properties/XXXXXXX%3ArunReport was not found on this server. That’s all we know.”

    Even I try “123456” as the access_token in the header, but the same error pops up. So, it looks like the POST is failing on the URL, not on Authorization.

    Weird thing is, the code works perfectly when posting to the API Explorer at https://developers.google.com/analytics/devguides/reporting/data/v1/rest/v1beta/properties/runReport. I enter properties/XXXXXX as the property and include the following request body:

    {
      "metrics": [
        {
          "name": "activeUsers"
        }
      ],
      "dimensions": [
        {
          "name": "country"
        }
      ],
      "dateRanges": [
        {
          "startDate": "2023-01-01",
          "endDate": "2023-02-20"
        }
      ]
    }

    Results are returned correctly. But when I try to POST to this URL, the same error comes up.

    I’m sure I’m overlooking something super obvious. Any ideas or advice? Anyone got an example of accessing GA4 without a client library? That would be so cool!

    William replied 1 year, 4 months ago 3 Members · 2 Replies
  • 2 Replies
  • Harper

    Member
    3 May 2023 at 8:55 am

    I see where you’re coming from, and I think there’s just a little mix-up! Your JSON is not behaving as expected because it should be sent as the POST “body” instead of as a formfield named “reportRequests”. Here’s an example:

    <cfscript>
        // Let's set up our JSON request
        requestJSON = {
           "dateRanges": [{ "startDate": "2023-01-01", "endDate": "2023-03-14" }],
           "dimensions": [{ "name": "sourceMedium" }, { "name": "transactionId" }, { "name": "date" }, { "name": "defaultChannelGroup" }, { "name": "campaignName"}],
            "metrics": [{ "name": "purchaseRevenue" }]
        };
        
        // And now let's send it out!
        cfhttp(method = 'POST', charset = 'utf-8', url = 'https://analyticsdata.googleapis.com/v1beta/properties/#brand.propertyId#:runReport', result = 'result') {
            cfhttpparam(name = 'Accept', type = 'header', value = 'application/json');
            cfhttpparam(name = 'Authorization', type = 'header', value = 'Bearer #accessToken#');
            cfhttpparam(type = 'body', value = serializeJSON(requestJSON));
        }
                    
        // Now we just need to parse our result
        GA4Data = deserializeJSON(result.fileContent);
    </cfscript>
    

    With this approach, I think you’ll be back on track in no time. Give it a try!

  • William

    Member
    3 May 2023 at 4:53 pm

    The error you’re receiving is indicating that the URL you’re trying to reach couldn’t be found on the server. The most likely cause for this is that there’s an issue with your URL construction. In the POST request, you’re adding a suffix of ‘:runReport’ to the base URL. However, according to the GA4 API documentation, ‘runReport’ should actually be part of the path, not a parameter.

    Second, when you’re assembling the JSON payload for the POST request, the JSON property names must be capitalized according to the GA4 API schema. In your code, “dateRanges”, “metrics”, and “dimensions” are all in uppercase, it should be in camelCase format as per the GA4 API.

    Lastly, check your authorization method. You’re using cfhttpparam type “formfield” to add your JSON payload, while you should use type “body” since you’re sending a JSON payload in a POST request. So rather than formfield, you would use cfhttpparam type=”body” for the JSON payload. Also ensure your content-type is set to application/json.

    Correct these issues and try again, it should work as expected. If you get further errors, make sure to check them against the details provided in the GA4 API documentation.

Log in to reply.