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

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.

Related

Cloudwatch Logs Insights aggregating data for application dashboard

I have a lambda function that makes a call to a ticketing API, and returns a list of tickets and their attributes (open/resolved, assignee, etc). I want to build a dashboard within CloudWatch to show this information but I'm not sure if I'm approaching the problem correctly.
For example if I wanted a visualization of "Open tickets which are assigned to Jason" which changes over time. I've tried using Log Insights, but the response message is an array of tickets, which I've not been able to successfully query. The logs are structured as:
{
"level": "INFO",
"location": "get_all_tickets:18",
"message": [
{
"ticketId": "001",
"status": "Open",
"assignee": "Jason",
"requester": "Paul",
"createdAt": "2022-10-20 11:08:35.105000+00:00",
"lastUpdatedAt": "2022-10-25 13:42:52.881000+00:00",
"title": "Example Ticket 1",
},
{
"ticketId": "002",
"status": "Resolved",
"assignee": "Jason",
"requester": "John",
"createdAt": "2022-10-20 11:09:35.105000+00:00",
"lastUpdatedAt": "2022-10-25 13:42:52.881000+00:00",
"title": "Example Ticket 2",
}
],
"timestamp": "2022-10-27 18:26:32,680+0000",
"service": "ticket_metrics"
}
Within Logs Insights the fields are serialized as message.0.status, message.1.status, etc, but I haven't found a way to query and aggregate these. Is there a way I can produce a metric, like the above example "Open Tickets assigned to Jason" from within Logs Insights?
I tried queries from the Logs Insights docs, but these didn't perform as expected or didn't apply to my use case.

Is there a way to delete user.organizations[1] in Google Admin Console?

Making a script to create uniform gmail signatures and I noticed only a few users, out of the hundreds, have both user.organizations[0] and user.organizations[1]. This of course is bothering me terribly. I see on these users that the 1 is the primary and visible in GAC while the rest of the users that is the 0 that is visible. Is there a way to delete the extra organizations inside a user?
Yes, this is possible and it is very simple.
We will need to use 2 methods:
Users.get (https://developers.google.com/admin-sdk/directory/reference/rest/v1/users/get) to check every user to confirm they have the correct value in the organizations property.
Users.update (https://developers.google.com/admin-sdk/directory/reference/rest/v1/users/update) to replace the existing value on that property.
Steps:
Feel free to use the API Explorer available in the documentation above to test these API calls.
Use the Users.get method to obtain the data of the user you are interested in updating. You can make the result shorter by specifying a value in the fields parameter like so:
"fields": "primaryEmail,organizations"
This will return the data of the user including their primary email and a list of the organization(s) the user has.
{
"primaryEmail": "user#domain.com",
"organizations": [
{
"title": "Accountant",
"primary": true,
"customType": "",
"department": "Accounting",
"description": "Full Time accountant",
"costCenter": "CompanyTotalPro"
},
{
"title": "Accountant",
"primary": false,
"customType": "",
"department": "Accounting",
"description": "Part Time accountant",
"costCenter": "SecondaryCompany"
}
]
}
This response will contain the data of one or more organizations, you will only need to copy the value you want to maintain and make an API call using the Users.update method. Like so:
Don't worry about the code. What you need to see is that we are essentially obtaining the list of organizations and removing the one we don't want, and using the new set of information to overwrite the old one. Use this for reference.
gapi.client.directory.users.update({
"userKey": "user#domain.com",
"resource": {
"organizations": [
{
"title": "Accountant",
"primary": true,
"customType": "",
"department": "Accounting",
"description": "Full Time accountant",
"costCenter": "CompanyTotalPro"
}
]
}
})
Use null to clear the value.
"organizations": null

Microsoft Teams: "Something went wrong" while installing my custom app into my organization's team

I have created an app for Microsoft Teams that one can add to a team. The app is a chatbot created with the Microsoft Bot framework. I have already made two other apps with similar functionality that can be installed fine.
When I create my app using the App Studio (and link to an existing bot), everything is fine but when I try to add that to a team I get the "something went wrong" message and no request is sent to my bot either...
Has anyone faced a similar issue or does someone know how to debug this? My manifest is below.
The manifest is below (with ids replaced).
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.5/MicrosoftTeams.schema.json",
"manifestVersion": "1.5",
"version": "0.0.2",
"id": "my-id-is-here",
"packageName": "nl.getsofia.teams.acceptance",
"developer": {
"name": "Sofia Melius B.V.",
"websiteUrl": "https://www.getsofia.nl",
"privacyUrl": "https://www.getsofia.nl/",
"termsOfUseUrl": "https://www.getsofia.nl/"
},
"icons": {
"color": "color.png",
"outline": "outline.png"
},
"name": {
"short": "Sofia Acceptance 2",
"full": "Sofia Acceptance Nice"
},
"description": {
"short": "ACCEPTANCE bot",
"full": "ACCEPTANCE bot long description"
},
"accentColor": "#FFFFFF",
"bots": [
{
"botId": "my-bot-id-is-here",
"scopes": [
"personal",
"team"
],
"commandLists": [
{
"scopes": [
"personal"
],
"commands": [
{
"title": "Add user",
"description": "A manager can add a user"
},
{
"title": "Get overview",
"description": "Get an overview of registered hours"
},
{
"title": "Projects",
"description": "Manage all projects"
},
{
"title": "Register hours",
"description": "Register your hours"
},
{
"title": "Settings",
"description": "Set hour registration reminder times"
}
]
}
],
"supportsFiles": false,
"isNotificationOnly": false
}
],
"permissions": [
"identity",
"messageTeamMembers"
],
"validDomains": [
"*.sofiamelius.nl",
"*.getsofia.nl"
]
}
If this is occurring when you are attempting to deploy the bot to Teams (as opposed to trying to talk to it in Teams), the "Sorry, something went wrong" message is usually caused by the Teams channel in the Bot Service not being set up. You must both set up the manifest and turn on the channel.
To turn on the channel, just navigate to your Bot Service in the Azure Portal, select the Channels blade, and then click on Teams to save and activate the channel (I can't remember but I don't think you have to configure any settings here).
After that is complete, you should be able to publish your bot to Teams using any available method.
I had the same problem trying to test with "Test team" team, which is apparently a special undeletable team that somehow exists in our teams.
Solution: Create a new Team and use your bot there.

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.