Google Analytics 4 Measurement Protocol shows events but no users - google-analytics-4

I would like to use Google Analytics from a script (using explicit HTTP requests) and understand that Google Analytics 4 with the Measurement Protocol would be the way to go. I have created a new Property, added a Web tag and created an API key for the Measurement Protocol there. Then I send this request:
{
"client_id": "Test-User",
"user_id": "test_user_id",
"events": [
{
"name": "MyEvent",
"params": {}
}
]
}
To this URL: https://www.google-analytics.com/mp/collect?measurement_id=G-LQDLGRLGZS&api_secret=JXGZ_CyvTt29ucNi9y0DkA
The measurement gets logged there in a corner of the report:
These events don't show up as users. And in reports I don't quite see how to analyze these events. Is there some way to track user sessions by sending special events?

I had the same problem and the answer is here
GA4 Measurement Protocol returns events not the users
Under the events branch of the JSON, when I added
"engagement_time_msec" : 1
the users started to be counted.
"events" : [{
"name" : "SoftMeter_event",
"params" : {
"action" : "From UA-xxxxx [muted]",
"engagement_time_msec" : 1,
"label" : "SoftMeter-dev/v1.0.2/lib v1.4.4 DEBUG"
}
}],
The Measurement Protocol V4 is for GA4 properties(which is also the
one you are using).
According to the official document:
https://support.google.com/analytics/answer/9408920 It says "Google
Analytics 4 properties counts users who engaged with your app/site for
any non-zero amount of time during the previous 30 minutes".
GA4 uses "engagement_time_msec" parameter to identify user interaction
time. This explains why you can see the number of events but not the
number of users. If you want users sent from MP to be counted as
active user, simply add the "engagement_time_msec" parameter to your
event.

client_id is wrong. This id is set by google, so you should get your real id.
You can get it from your cookies for testing. Or, if you use gtag.js you can add this code to your web page.
<script>
gtag('get', <yourMeasurementID>, 'client_id', (clientID) => {
// here you can use clientID
});
</script>

Related

How do I use the "since" parameter in the changes feed of a Cloudant DB?

I am working with a Cloudant db and would like to use the since param in the changes feed using the _changes API call. Was looking for guidance one what would be valid entries for the since parameter. I know 0 and now are options but is there a way to get changes from a defined time period?
Whenever you call the _changes API endpoint, you get a last_seq parameter in the response. This is a token that can be supplied to the _changes endpoint in a subsequent API call to get the next batch of changes.
For example, if you make an initial call to get changes in a database called orders:
GET /orders/_changes?limit=5
{
"results": [
{
"seq": "1-g1AAAAB5eJzLYWBg",
"id": "00002Sc12XI8HD0YIBJ92n9ozC0Z7TaO",
"changes": [
{
"rev": "1-3ef45fdbb0a5245634dc31be69db35f7"
}
]
},
....
],
"last_seq": "5-g1AAAAB5eJzLYWBg"
}
...you can then get subsequent changes by using the returned last_seq parameter:
GET /orders/_changes?limit=5&since=5-g1AAAAB5eJzLYWBg
{
"results": [ ...],
"last_seq": "10-g1AAAACbeJzLY"
}
However, it should be noted that programming against this changes feed is complicated for a number of reasons. For example, the changes are not strictly ordered in time sequence and may be duplicated between calls. Please read this FAQ document for more details.

how to query custom dimension google anaylitics api

I have setup a custom dimension in google analytics 'dimension2' into which I want to capture a WPForms UniqueID. I added this to Google Tag manager and I can see the custom dimension with a value when I preview site in GTA preview.
. I added this to gtags.js on this word press site,
var dimensionValue = $.cookie("_wpfuuid");
gtag('config', 'UA-1234567890-2', {
'custom_map': {'dimension2': 'wpfid'}
});
gtag('set', 'dimension2', {'wpfid': dimensionValue});
In google analytics query explorer, I can see dimension2 in the test results.
"columnHeaders": [
{
"name": "ga:dimension2",
"columnType": "DIMENSION",
"dataType": "STRING"
},
{
"name": "ga:users",
"columnType": "METRIC",
"dataType": "INTEGER"
}
],
"totalsForAllResults": {
"ga:users": "1"
},
"rows": [
[
"40502794-ecf1-4cf6-97b9-2c16c7f6c949",
"1"
]
]
And, I can see the dimension2 data in google analytics user explorer, so it is making it to the browser interface for analytics.
However, when I add the following to my API query script, it breaks and is not generating any php errors, or the error is that it does not recognize 'dimension2'. I tried this on 2 views and both act the same. Here is my code to add the custom dimension to my query
$dimension = new Google_Service_AnalyticsReporting_Dimension();
$dimension->setName("ga:dimension2");
What am I missing? Why isn't this visible in google api results and/or where I can I see any errors?
Some hours later, this code started to work, which suggests to me that custom dimensions are not immediately available to the api. In this case the api recognized dimension2 long after the data was visible in the analytics website.
Second possibility to check which can cause this seemingly good code to not work, you are using the wrong view id. Of the 2 views I tested, this only works on one.

Setting Conversion Window/Ads Action Stats via Facebook Ads Api

I have a requirement to add 'Conversion Window' (as above) to an existing Java application which creates batches of Facebook ads. I can't find how to set Conversion Window via the API or how to get a list of them from the API.
This is the most relevant information I've found:
https://developers.facebook.com/docs/marketing-api/reference/ads-action-stats
But it doesn't give me all of what I need.
Although named similarly, those are two different things.
Conversion window specified with bidding is a time period used for optimization of ad delivery. The parameter is called attribution_specand can be set on adset. Valid combinations are described here.
Adset with conversion window of 1-day view, 7-day click would be specified like this:
{
"name": "Adset name",
"attribution_spec": [
{
"event_type": "VIEW_THROUGH",
"window_days": 1
},
{
"event_type": "CLICK_THROUGH",
"window_days": 7
}
],
... other adset params ...
}
Attribution window is a parameter used when loading insights. Using that you can get the stats broken down into different time periods, which can be handy for advanced analytics.

Breakdown parameters for the application insights

According to the Facebook documentation for the app insights (link) one can specify breakdowns parameters, namely app_event_parameter1, app_event_parameter2 etc. However, I failed to find any information how to do it. So, the question is where and how exactly to specify these parameters?
The names app_event_parameter1, ..., app_event_parameter10 are slightly misleading since the other breakdowns in the table are used exactly as listed.
For example, you would request the breakdowns client and auth_state like this:
{
"period": "monthly",
"breakdowns[0]": "client",
"breakdowns[1]": "auth_state"
}
However, if you've been logging a custom app event with a custom parameter "game_level" then you'd request that breakdown like this:
{
"period": "monthly",
"breakdowns[0]": "game_level",
}
You can supply up to 10 of your own app event parameter names as breakdowns.

REST design for API accessing multiple resources

Imagine an API that returns JSON data for a TV listings app like zap2it TV listings.
It's basically a list of TV channels and for each channel the shows that are on currently and beyond. Currently, I have an API that returns all the channels GET /channels. However, there is a need to add the show currently on for each channel in that data. I am thinking of adding a new API, GET /channels/on_now, to differentiate it from the current API. I want to be clear about this for the new API, I don't want to make individual call for each channel, the show-on-now data needs to be returned for all channels. Is this a good REST API design?
Current GET /channels JSON data
[
"channel": {
"channelName": "KRON4",
},
"channel": {
"channelName": "KTOV5",
},
...
]
Expected JSON data for new API GET /channels/on_now below
[
{
"channel": {
"channelName": "KRON4",
},
"on_now": {
"startTime": "2012-06-04T11:30:00",
"endTime": "2012-06-04T12:00:00",
"shortDescription": "Latest local, statewide & national news events, along with sports & weather.",
"shortTitle": "4:30am Newscast"
}
},
{
"channel": {
"channelName": "KTOV5",
},
"on_now": {
"startTime": "2012-06-04T11:30:00",
"endTime": "2012-06-04T12:30:00",
"shortDescription": "Local morning news and weather report",
"shortTitle": "Morning Newscast"
}
},
...next channel...
]
I would advice to concentrate on content, not on URLs.
Example: you've got an entry point, '/'. This is the only URL in the API. GET on it return st like
{
"channels" : {
"href" : "path.to/channels"
},
"programs" : {
"href" : "path.to/programs"
}
}
To retrieve the list of channels, you GET on the corresponding URL - which you then don't need to know before - and obtain, for example:
[
{
"name" : "BBC",
"id" : 452,
"href" : "path.to/channels/452"
},
{
"name" : "FOO",
"id" : 112,
"href" : "path.to/channels/112"
}
]
For detailled information about BBC, you GET on the provided URL:
{
"name" : "BBC",
"id" : 452,
"self" : "path.to/channels/452",
"live_url" : "link.to.bbc.cast",
"whatever" : "bar",
"current" : "path.to/channels/452/current",
"program" : "path.to/channels/452/program"
}
And so on. URLs are discovered on the fly; you are free to modify them anytime. What makes your API is the content: you have to agree with clients about what is returned (fields, types, ...).
You finally call the "current" URL above to obtain information about current program.
Read here for more: http://kellabyte.com/2011/09/04/clarifying-rest/
Edit after OP-comment:
You could introduce an 'embed' parameter so as to limit amount of requests:
GET path.to/channels/452?embed=current
would return:
{
"name" : "BBC",
"id" : 452,
"self" : "path.to/channels/452",
"live_url" : "link.to.bbc.cast",
"whatever" : "bar",
"current" : {
"self" : "path.to/channels/452/current",
"name" : "Morning Show",
"start_time" : "(datetime here)",
"end_time" : "(datetime here)",
"next" : "whatever.comes.ne/xt"
},
"program" : "path.to/channels/452/program"
}
You asked:
Is this a good REST API design?
YES, it is.
Contrary to the other people who have answered, you are free to define any resource you want to, as long as it represents a noun. That includes time-dependent services such as "what's on TV now" or the perrenial example, "current weather in <city>". These service resources are just as valid as more static ones representing a show or channel.
I would however change the URI. /channels looks like a collection resource URI. I would expect it's children to be channels, such as /channels/kron4 (you can use any unique string, not jsut the ID, to identify instance resources).
As such, /channels/on_now looks odd. It looks like a channel called "on_now". Although there's nothing preventing you from using that, it may later conflict with a channel that is called "On Now"! I would simply use /on_now as your URI. /channels/kron4/on_now would obviously be good for a single channel's response too.
/Channels -----------------------> Get All Channels
/Channels/bbc ------------------> Get BBC Channel
/Channels/bbc/Shows -------------> Get All shows in BBC
/Channels/bbc/Shows/Baseball ----> Get the show called "Baseball", in bbc channel
/Channels/bbc/Shows/current -----> Get the Current show running, in bbc channel
Assuming you do not (and will not ) have a show called Current for any of your channels ! :) .
Just appending to the above answer:
/Channels/bbc/Shows/time/now -----> Get all the show played on BBC now
/Channels/bbc/Shows/time/2011-03-27T03:00:00.000+02:00 -----> Get all the show played on BBC on 2011-03-27T03:00:00.000+02:00 .
This is more extensible and you wont have to worry about any show with the name current.
EDIT:
You can get a good headstart of doing such thing if you can get an api-doc access over here https://developer.sdp.nds.com/page/about
As per me, there would be more data needed and api would be something like:
//epg?time=&start=0&limit=1&duration=
This would define a generic api to get the location based tv_listing information based on time and duration. Result would be paginated with all the show between the channel listing occuring in the given time span.
I'm no API expert, but I think you should be thinking in what you are returning instead of where 'looks like makes sense' to place the resource.
One solution will be to treat on_now as a resource.
so your api will be:
/channels (all channels)
/channels/{channel-id} (the {channel-id} channel - could be bbc and can have a collection of shows)
/channels/{channel-id}/shows (shows of channel-id)
/channels/{channel-id}/shows?filter=on_now (you are filtering a result, so i guess it's better to use query string, as if you were doing a query)
then you want to returns what's on now, that's no a property of the channel but a resource of itself. so how to implement that ?
/on_now/ (return a collection of on_now objects, which may be anything, channels, shows, whatever)
/on_now/?channel={channel-id} (this is a filter of the list by channel-id, you are just narrowing the list)
so isn't /channels/{channel-id}/shows?filter=on_now
the same as /on_now/?channel={channel-id} ?
actually, NO.
In the first uri you are getting shows filtered by a on_now.
In the second you are getting on_nows (which can be any representation, not exclusively a show) filtered by channel.
Why I think on_now should be treated as a resource and why is it important ?
While you make this resource separate, you can now have different representations of your resources. Also you have greater flexibility and no collision. Let's say tomorrow you want to show also in the on_now another 'show' that isn't on any channel, this can easily be done, on the other approachs it just has to be on a channel.
You can also later filter the on_now by different criteria, because they are independent objects.
You can also do:
/on_now/{on_now_id}
that will give details of the current show, like when it started, when it will end and also a place a location to /shows/{show-id} so you can reach it later after it's not on now anymore.
Yet, I think best solution would be to have shows as an unconnected resource to channel.
But the most important thing is, i think you should also need to ask yourself if you want shows to be underlying of channels...
And what hints to think of that is the
I don't want to make individual call for each channel, the
show-on-now data needs to be returned for all channels
part.
That leads me to think that shows should NOT be inside the /channels/ path.
That's because another approach will be to have /shows/?filter=on_now if you are only returning shows.
you can have:
/shows/?filters=on_now&channel=bbc
I like to think of resources as the 'thing' i'm returning instead of the standard thinking of relations alone. Underlying in the graph is great for properties, not so sure about collection of 'other things'.
Following the same example, I would rather have /channels/{channel-id}/program instead of /channels/{channel-id}/shows