I am working on developing integration with Google Calendar using Rest API. I got to know Google applies both rateLimit and usageLimit on API calls - 403_calendar_usage_limits_exceeded
In case I breach the limits, I want to wait for a defined period of time before I retry the request again. Is there any way to know if there is something like Retry-After header returned by Google.
I checked documentation but not able to find anything related - errors
You can see your quota in google developer console under libary search for google calendar and then click the manage button. Under the quota tab you will see something like this.
There are two types of quota user based quota denoted by the "per user" and project based quotas.
Each user running my application can make a max of 600 requests per minute. if they make to many then i will get a quota exception.
My application can make a max of 10000 request per minute in total. if it makes more then that then again i will get a quota exception.
You may want to read though Manage quotas this explains a lot about quota usage and the google calendar api.
For the most part if you just implement exponential backoff you should be able to avoid to many of these errors.
try request if fails
wait 10 seconds
try again if fails
wait 20 seconds
try again if fails
wait 30 seconds
try again
.......
Is it possible to use GA4 Measurement Protocol to send events to Google Analytics and view and analyze them in the GA dashboard without using gtag.js or any other front-end script? The use case would be that some events are being sent to my server and I will just push these events to GA through the API.
One thing that makes me think is that the official Measurement Protocol API say:
In order for an event to be valid, it must have a client_id that has already been used to send an event from gtag.js. You will need to capture this ID client-side and include it in your call to the measurement protocol. In send an event to your property, we use "client_id" as the client_id. You will need to replace this with a real client_id that comes from gtag.js.
(https://developers.google.com/analytics/devguides/collection/protocol/ga4/verify-implementation?client_type=gtag)
That suggests that only events that have a valid client_id that originate from gtag.js will be counted.
I did some experimenting with randomly generated client_ids and what I discovered was that I was able to see my events in the Realtime section of the GA4 console (the Event count by Event name section), but all the other sections would be empty and the Users in last 30 min section would always show 0.
Can someone please explain to me why it's zero and if such a use case is valid at all? Thanks
tl;dr
You can use any value in client_id, as long as it uniquely identifies the user (we use a GUID/UUID), but it seems like you also need to send a value in user_id. We use the same value for both.
Also, you need to add the 'engagement_time_msec' parameter to get any user metrics to register.
Longer answer:
We're trying to do the same, i.e. send all events to the GA4 Measurement Protocol from the server, so that it is not dependent on the current user's GDPR cookie settings.
We currently do this for a Universal Analytics property with no issues, but it seems that Google is trying to prevent this in future, by restricting the scope of the Measurement Protocol in GA4, whilst forcing everyone to move to it by July 1st 2023. See the documentation at https://developers.google.com/analytics/devguides/collection/protocol/ga4#full_server-to-server, where it states:
While it is possible to send events to Google Analytics solely with
measurement protocol, only partial reporting may be available. The
purpose of measurement protocol is to augment existing events
collected via gtag, GTM, or Firebase.
We have something working with GA4, in that the events are being registered on the GA4 property correctly, using a client id that is just a GUID/UUID that we define in our own site cookies. So, any value can be used in the client id, as long as it uniquely identifies the user. The same value is used to populate the user_id parameter.
When sending events, the realtime event details were showing on the GA4 dashboard, but user metrics were not until we also populated the 'engagement_time_msec' parameter, as described in https://stackoverflow.com/a/71482548/7205473
We still have issues with things like getting the user location and the platform details, which previously were automatically populated by passing the IP address and the User Agent, but which seem to no longer work in GA4.
We were also passing page load timing events through the Measurement Protocol, but again, these features seem to have been removed in GA4.
It is possible to use GA4 directly without gtag.ja or the Firebase SDK. Its not supported, so it takes some work. We have this working in a desktop app reasonably well. There a couple things that need to be done.
As stated elsewhere the "engagement_time_msec" param must be set using the "_et" parameter. This is the number of milliseconds between now and the previous event.
The client id "cid" has a specific format; it should be:
"randomNumbers(10).unixTimeStamp()"
The session id "sid" format is:
"randomNumbers(10)"
The "_z" parameter needs to be set. I think this is a cache buster. Looking deep into the gtag.js code it is a url safe base64 encoding of "CCD", which always results in the value "ccd.v9b"
The page hash parameter "_p" can be set to this; not totally sure its correct but it works.
"randomString(3).randomString(3)"
Set the "User-Agent" HTTP request header in whatever framework/lib you are using. GA4 uses this to determine many things including Operating System. You will need to create a fake user agent based on the local device information. This is what we use for a Windows 11 x64:
"myco.testapp/4.0.0 (Windows NT 10.0; Win64; x64)"
The IP will be taken fromn the web request which is where the geolocation data comes from.
Since a full working example is worth 1,000 words of documentation; here is a "test" event with a parameter "animal=dog":
https://www.google-analytics.com/g/collect?cid=0078745494.1659679529&_et=364&_p=pfJ.Aev&seg=1&sid=2678664821&tid=G-???&ul=en&v=2&_z=ccd.v9b&en=test&ep.animal=dog
It's possible to extract outgoing GA4 request from a GTM container debug/preview view and map any GA4 (automatically collected and custom) event.
Example page_view request URL:
https://www.google-analytics.com/g/collect?v=2&tid=G-XXXXXXXXXX>m=3oes1i1&_p=1545013558&_dbg=1&cid=P%2FdJWyULMwcT21TMrzn7pZdlNt%2FxtttGVqGUmqNYbhc%3D.1669722847&ul=nl-nl&sr=2560x1440&uaa=x86&uab=64&uafvl=Not_A%2520Brand%3B99.0.0.0%7CGoogle%2520Chrome%3B109.0.5414.75%7CChromium%3B109.0.5414.75&uamb=0&uam=&uap=Windows&uapv=10.0.0&uaw=0&_s=1&_uip=XXX.XXX.XXX.X&sid=1674235261&sct=1&dl=https%3A%2F%2FXXXXXXXXXX.com%2F%3Fgtm_debug%3D1674235654105&dr=https%3A%2F%2Ftagassistant.google.com%2F&dt=OM%20test&jscid=XXXXXXXXXX.1669722847&seg=1&en=page_view
Tip: use Postman to analyse and experiment with parameters
regardless of the platform used to make a call the Measurement Protocol, you should use a client id generated by gtag.js, or the app ID if using Firebase.
I am creating a room resource via the Google Workspace Admin API. However there is no parameter to specify the Calendar-based room release. It is alway set to Off but I would like to have it set to On.
Is there anyway to do that with any Google API?
Issue:
Currently, you can only turn room releases on or off via Admin console. This is not possible via Directory API in the current implementation.
File a feature request:
I'd suggest you to file a feature request in Issue Tracker (here is the corresponding template), if you think this functionality could be useful.
Update - Feature request filed:
Room release parameter for ressources can not be changed via Directory API
Reference:
Free unused Google Calendar meeting rooms
REST Resource: resources.calendars
In my company we set up Google Calendar API to notify our providers when we have new missions to offer them and allow them to accept/refuse mission through the Google Calendar.
However, since last week we started getting quotaExceeded errors ("Calendar usage limits exceeded"). I checked quotas but figured out we are way below quotas (3,000 / 1,000,000 requests per day and 10 / 500 requests per 100 seconds).
HttpError: <HttpError 403 when requesting https://www.googleapis.com/calendar/v3/calendars/svbk5reui******l6h044qn3h4%40group.calendar.google.com/events/1meqllvk6******dt9poej9mk0?alt=json&sendNotifications=true returned "Calendar usage limits exceeded.">
After checking a bit further, I noticed there are also "hidden" quotas. I say "hidden" quotas beacause I can't find any feedback about the evolution of these quotas. I assumed we might have reached either "Send too many invitations to external guests" or "Email too many guests via Google Calendar events" quota. So I set sendNotifications=false where we used to set sendNotifications=true.
Since I made this change, we didn't experience the quotaExceeded error anymore. However, our providers are also not notified anymore when we offer them a new mission. So, I doubled the API calls with an e-mail sent to the providers including the link to the Google Calendar event.
Yet, now, some of them can't access the link, and the other can't answer if they will be attending the event or not.
How come setting sendNotifications=false disallows access or answering to the attendees? Can I check exactly what quotas are exceeded? And what are my solutions to notify our providers about new missions and allow them to see it in their calendar and answer it?
We're tracking some resources in google calendar using push notifications api. These channels have finite lifetime, so they expire and there is no way to renew it. I'm setting up a cron to start new channel in case old one had expired. Without knowledge of existing channels, only option is to start a channel every now and then to be sure that given resources are being watched.
Is it possible to check if a resource is being watched by an active channel in google calendar api?
GCal's API doesn't allow you to request that directly, so you'd have to handle that logic.
Here's an example of how you could keep your channels active:
When creating a channel, include the expiration time and persist that value somewhere
During your cron task, check if it's beyond the expiration time
If so, create a new channel
If not, check if it will expire before the next cron run
If so, renew it now
Optional: Delete the original watch channel (so no overlaps)
If not, continue
Another approach would be to use refresh tokens to ensure API access, without having to worry about whether a channel is expired or not.
Google Calendar API overview
Node client example