Google Calendar JSON API: Full-day events always one day longer - json

Since recently the JSON API always seems to add a day when returning the timespan for full-day events.
Display in Google Calendar Web app:
Yet what the JSON API returns is this:
{
"kind": "calendar#event",
"etag": "\"2896554426340000\"",
"id": "...",
"status": "confirmed",
"htmlLink": "https://calendar.google.com/calendar/event?eid=...",
[...]
"summary": "...",
[...]
"start": {
"date": "2016-02-01"
},
"end": {
"date": "2016-02-02"
},
[...]
"iCalUID": "...#google.com",
"sequence": 0
}

In the Calendar API the start is inclusive and the end is exclusive. That's why the end will be the next day (which is excluded).

Related

Looking for a way to filter data withing Azure API call

I am looking for a way to extract data out of an azure environment. Problem i'm currently having is that when I use my API call I receive about 60 lines of json while I only need 4 of those lines. To reduce load, increase efficiency and remove the need for parsing withing the other environment where I need to data, I want to find a way to filter the data in the api call. Currently my call looks like this.
https://management.azure.com/subscriptions/{subscription}/resourceGroups/{resourcegroup}/providers/Microsoft.Web/sites/{application or resource}/providers/microsoft.insights/metrics?api-version=2021-05-01&metricnames=IoWriteBytesPerSecond,IoReadBytesPerSecond&timeSpan=PT1M
now the ouput looks something like this.
{
"cost": 0,
"timespan": "2022-10-11T10:18:00Z/2022-10-11T10:19:00Z",
"interval": "PT1M",
"value": [
{
"id": "/subscriptions//resourceGroups//providers/Microsoft.Web/sites//providers/Microsoft.Insights/metrics/IoWriteBytesPerSecond",
"type": "Microsoft.Insights/metrics",
"name": {
"value": "IoWriteBytesPerSecond",
"localizedValue": "IO Write Bytes Per Second"
},
"displayDescription": "The rate at which the app process is writing bytes to I/O operations. For WebApps and FunctionApps.",
"unit": "BytesPerSecond",
"timeseries": [
{
"metadatavalues": [],
"data": [
{
"timeStamp": "2022-10-11T10:18:00Z",
"total": 288.0
}
]
}
],
"errorCode": "Success"
},
{
"id": "/subscriptions//resourceGroups//providers/Microsoft.Web/sites//providers/Microsoft.Insights/metrics/IoReadBytesPerSecond",
"type": "Microsoft.Insights/metrics",
"name": {
"value": "IoReadBytesPerSecond",
"localizedValue": "IO Read Bytes Per Second"
},
"displayDescription": "The rate at which the app process is reading bytes from I/O operations. For WebApps and FunctionApps.",
"unit": "BytesPerSecond",
"timeseries": [
{
"metadatavalues": [],
"data": [
{
"timeStamp": "2022-10-11T10:18:00Z",
"total": 284.0
}
]
}
],
"errorCode": "Success"
}
],
"namespace": "Microsoft.Web/sites",
"resourceregion": "westeurope"
}
Out of all these lines I only need about 4 objects, Is it possible to use the $filter function within the URL api call? If yes, can someone redirect me to a forum, doc or example where this is used?
Thanks, regards

How do I test for Google Calendar events that are marked: "Automatically decline new and existing meetings"

Non-engineer here. I'm working on a program (using Google Sheets) that will help people in my office analyze their calendars.
The Google Calendar Service has methods that allow me to retrieve event start and end times, guest lists, and much more. Unfortunately, I haven't figured out how to tell the difference between a "Reminder" and an "Out of the office" event. They both show up as all day events, but the former can be ignored and the latter causes that entire day to show up as "blocked" or "scheduled". I need to be able to tell them apart, but I'm not sure how.
Any suggestions?
MORE DETAIL:
I create a "Reminder" in Google Calendar by clicking just below the day, at the top. This gives me three choices: Event, Out of the office, and Appointment slots. When I am creating a Reminder for myself I first name it (i.e. "Doctor's appointment at 2:00"), then I usually change the color to red so it's extra visible.
If I am going to be Out of the office I choose that option. The option "Automatically decline new and existing meetings" is checked by default. I add a name like, "Dev Conference" and Save it. This causes the entire day to show in a light blue color, indicating that the entire day is blocked.
You can differentiate between a normal event and a "Out of Office" event because of the latter not having the transparency attribute included and it has the description attribute filled with the following value:
"This is an out-of-office event, which can only be edited in Google Calendar. Meetings during this time will be automatically declined."
You can test this by making a Events.list request and check the results, for example:
Normal event:
{
"kind": "calendar#event",
"etag": "\"3167876463844000\"",
"id": "1nqq8sg43po8itr8h0ebedfgbq",
"status": "confirmed",
"htmlLink": "https://www.google.com/calendar/event?eid=MW5xcThzZzQzcG84aXRyOGgwZWJlZGZnYnEgdGVzdGluYUBlZ3Mtc2J0MDExLmV1",
"created": "2020-03-11T14:50:31.000Z",
"updated": "2020-03-11T14:50:31.922Z",
"summary": "test",
"creator": {
"email": "testina#egs-sbt011.eu",
"self": true
},
"organizer": {
"email": "testina#egs-sbt011.eu",
"self": true
},
"start": {
"date": "2020-03-16"
},
"end": {
"date": "2020-03-17"
},
"transparency": "transparent",
"iCalUID": "1nqq8sg43po8itr8h0ebedfgbq#google.com",
"sequence": 0,
"reminders": {
"useDefault": false
}
}
Out of Office event:
{
"kind": "calendar#event",
"etag": "\"3167876472386000\"",
"id": "29g3lpl9hojb92bevvkvdccq6p",
"status": "confirmed",
"htmlLink": "https://www.google.com/calendar/event?eid=MjlnM2xwbDlob2piOTJiZXZ2a3ZkY2NxNnAgdGVzdGluYUBlZ3Mtc2J0MDExLmV1",
"created": "2020-03-11T14:50:36.000Z",
"updated": "2020-03-11T14:50:36.289Z",
"summary": "test OOO",
"description": "This is an out-of-office event, which can only be edited in Google Calendar. Meetings during this time will be automatically declined.",
"creator": {
"email": "testina#egs-sbt011.eu",
"self": true
},
"organizer": {
"email": "testina#egs-sbt011.eu",
"self": true
},
"start": {
"dateTime": "2020-03-17T00:00:00+01:00"
},
"end": {
"dateTime": "2020-03-18T00:00:00+01:00"
},
"visibility": "public",
"iCalUID": "29g3lpl9hojb92bevvkvdccq6p#google.com",
"sequence": 0,
"reminders": {
"useDefault": false
}
}
Regarding appointment slots, these are not supported by Google Calendar API, you can +1 this open feature request to implement this.
For a while after the feature was introduced, there was no way to filter them via API other than parsing the description. There is now an eventType key on events.
https://developers.google.com/calendar/api/v3/reference/events#eventType
Look for "eventType": "outOfOffice" events.

Root Site Facet not returned on sites/search call

When making a call to the Microsoft Graph /sites?search endpoint, a root site facet is not returned.
Here is an example of the search:
https://graph.microsoft.com/v1.0/sites?search=fake Archive
It returns:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites",
"value": [{
"createdDateTime": "2017-11-04T18:52:44Z",
"id": "fakeau.sharepoint.com,0f736b6a-d7fa-498d-b13f-72af82d58b49,7c055ac7-0d31-4341-8158-8055950f37c8",
"lastModifiedDateTime": "2017-11-14T23:21:51Z",
"name": "fake Archive",
"webUrl": "https://fakeau.sharepoint.com/sites/fake Archive",
"displayName": "fake fake Archive"
}]
}
There is no root site facet. If I use the /site endpoint to access the site directly:
https://graph.microsoft.com/v1.0/sites/fakeau.sharepoint.com,0f736b6a-d7fa-498d-b13f-72af82d58b49,7c055ac7-0d31-4341-8158-8055950f37c8
I get the response:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites/$entity",
"createdDateTime": "2017-11-14T23:19:51.437Z",
"description": "",
"id": "fakeau.sharepoint.com,0f736b6a-d7fa-498d-b13f-72af82d58b49,7c055ac7-0d31-4341-8158-8055950f37c8",
"lastModifiedDateTime": "2018-03-23T12:23:40Z",
"name": "fake Archive",
"webUrl": "https://fakeau.sharepoint.com/sites/fake Archive",
"root": {},
"siteCollection": {
"hostname": "fakeau.sharepoint.com"
},
"displayName": "fake fake Archive"
}
Notice this now has a root site facet.
Is this a bug, or are there some situations in which the root site facet should not be shown in the /sites?search results?
The sites/search endpoint only returns a small subset of a site's properties:
id, name, description, createdDateTime,lastModifiedDateTime, and webUrl.
In order to retrieve the full metadata, you'll need to make subsequent requests to the /sites/{id} endpoint.

Create an Event with a specific iCalUid

Is there a way to create an event in Office calendar ( with the Graph API ) setting the iCalUId?
I have tested with the Graph Explorer tool (from the web site) inserting this event (POST /v1.0/me/events):
{
"subject": "My event",
"start": {
"dateTime": "2018-02-19T10:39:01.355Z",
"timeZone": "UTC"
},
"end": {
"dateTime": "2018-02-26T10:39:01.355Z",
"timeZone": "UTC"
},
"iCalUid": "040000008200E00074C5B7101A82E00800000000F44A7CFB6DA9D301000000000000000100000004A4B349D0E9F1744BBA2F67E4D522179"
}
The system creates my event correctly, but it changes the UID with another ( auto-created, I suppose).
This is a part of the JSON response:
{
"iCalUId": "040000008200E00074C5B7101A82E008000000005BBB3A076EA9D301000000000000000010000000389E2C56CB68B74E807FE83A5CC60AAB",
"subject": "My event",
"start": {
"dateTime": "2018-02-19T10:39:01.3550000",
"timeZone": "UTC"
},
"end": {
"dateTime": "2018-02-26T10:39:01.3550000",
"timeZone": "UTC"
}
}
From the documentation only the ID field is read-only, so I am wondering if there is a way to set the iCalUId.
iCalUid is a read-only calculated value so it cannot be manually set. You can see the details on how it is calculated in the PidLidGlobalObjectId Property documentation.
Here's an undocumented way (as far as I can tell, anyway) to modify the iCalUId. I've only tested with creation and not with updating, but I think it should work. Note that I don't know what other side-effects this will have, but for my use-case, it has worked so far.
The iCalUId gets its value from the PidLidGlobalObjectId property. You can modify this value using SingleValueExtendedProperties. For instances of recurring events, the iCalUId uses the PidLidCleanGlobalObjectId which oddly enough doesn't calculate its value from the normal PidLidGlobalObjectId, so you'll want to modify that too.
{
"subject": "Subject",
"start": ...,
"end": ...,
// the rest of your event request
"singleValueExtendedProperties": [
// PidLidGlobalObjectId
{
"id": "Binary {6ED8DA90-450B-101B-98DA-00AA003F1305} Id 0x003",
"value": "" // base-64 encoded PidLidGlobalObjectId, it should start with BAAAA...
},
// PidLidCleanGlobalObjectId
{
"id": "Binary {6ED8DA90-450B-101B-98DA-00AA003F1305} Id 0x023",
"value": "" // base-64 encoded PidLidCleanGlobalObjectId, it should start with BAAAA...
}
]
}
Be sure to check out the format
of the PidLidGlobalObjectId and PidLidCleanGlobalObjectId, otherwise you might get "Data is corrupt" or some other such errors when trying to create or update events.

How to add date/time exception to recurring Google calendar event

I have code that is creating Google calendar entries (recurring events) using the Google calendar API. This is working fine. Now I am trying to add exceptions to certain instances. I've got it working for deleted instances (by using the EXDATE parameter) but I'm having trouble changing the date/time of an instance. I am following the instructions found here:
https://developers.google.com/google-apps/calendar/recurringevents
After I create the basic recurring event, I retrieve a list of all instances. For testing, I am pulling out the entire section of json that applies to the instance I want to change, for example:
{
"kind": "calendar#event",
"etag": "\"3032281375946000\"",
"id": "_69j3ge9iccp68or1c8p3ac1nccpm8p356gpj8pb66koj2c32c5h0_20180130T203000Z",
"status": "confirmed",
"htmlLink": "https://www.google.com/calendar/event?eid=XzY5ajNnZTlpY2NwNjhvcjFjOHAzYWMxbmNjcG04cDM1NmdwajhwYjY2a29qMmMzMmM1aDBfMjAxODAxMzBUMjAzMDAwWiBqbWNrYXk5MzUxQG0",
"created": "2018-01-16T20:08:56.000Z",
"updated": "2018-01-17T00:13:59.277Z",
"summary": "Recurring test with deletes and changes",
"description": "\n",
"location": "SEattle",
"creator": {
"email": "jmckay9351#gmail.com",
"displayName": "Jeffrey McKay",
"self": true
},
"organizer": {
"email": "jmckay9351#gmail.com",
"displayName": "Jeffrey McKay",
"self": true
},
"start": {
"dateTime": "2018-01-30T13:30:00-08:00"
},
"end": {
"dateTime": "2018-01-30T14:00:00-08:00"
},
"recurringEventId": "_69j3ge9iccp68or1c8p3ac1nccpm8p356gpj8pb66koj2c32c5h0",
"originalStartTime": {
"dateTime": "2018-01-30T12:30:00-08:00"
},
"iCalUID": "2f892c2dcab2507c3dde434ef5110bab",
"sequence": 0,
"reminders": {
"useDefault": false,
"overrides": [{
"method": "popup",
"minutes": 15
}]
}
}
Then I do a http PUT of this data to this URL:
https://www.googleapis.com/calendar/v3/calendars/jmckay9351#gmail.com/events/_69j3ge9iccp68or1c8p3ac1nccpm8p356gpj8pb66koj2c32c5h0_20180130T203000Z
What I get back is a http error 400, and the error message in the returned json is "Missing end time". I get the same response regardless of how much or little data I feed into the PUT. Any idea what I'm doing wrong here?
OK I've got this working now - I don't understand what was wrong with my libcurl PUT code, but I changed it to be a POST with a custom request of "PUT" and that seemed to get to data correctly uploaded.