Create an Event with a specific iCalUid - json

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.

Related

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

Get a New Event Summary and Description

Trying to find a way to get the Summary and Description of a new Event.
I can get the attendees, conference data and event id that will be persisted when event is saved, but no reference to Summary or Description.
Example payload passed to the 'eventOpenTrigger' and 'eventUpdateTrigger':
{
"commonEventObject": {
"platform": "WEB",
"hostApp": "CALENDAR"
},
"calendar": {
"conferenceData": {
"conferenceSolution": {
"key": {},
"iconUri": "https://lh3.googleusercontent.com/...",
"name": "Test"
},
"notes": "test",
"parameters": {
"addOnParameters": {}
},
"conferenceId": "test",
"entryPoints": [
{
"uri": "https://test",
"entryPointType": "video",
"label": "test"
}
]
},
"id": "EVENT_ID",
"calendarId": "email#company.com",
"organizer": {
"email": "email#company.com"
},
"capabilities": {
"canSeeAttendees": true,
"canSetConferenceData": true,
"canAddAttendees": true,
"canSeeConferenceData": true
},
"attendees": [
{
"email": "email#company.com",
"self": true,
"displayName": "email#company.com",
"organizer": true
}
]
},
"hostApp": "calendar",
"clientPlatform": "web"
}
When try to use Calendar.Events.get(calendarId, eventId) to get more event details, it returns 404, which makes sense since the Event is not yet persisted. Just would be nice to be able to get the event Summary and Description at the time a user creates an event rather than having to have them reopen it again afterwards
It's intended behavior that the calendar event object does not return you the event summary and description, see also here
However, if you are able to trigger the eventOpenTrigger, you should also be able to use the method Events: get with the eventid the event object returns you.
Make sure you specify the calendar id and event id for the requets correctly. You can also test with the Try this API first before implementing the request into your code.
Since 'eventOpenTrigger' and 'eventUpdateTrigger' fire when an (already saved event) is being clicked on or when the Save button is clicked when a user modifies an event - there should not be any issues with the event not being saved yet.
The Calendar API documentation specifies that a 404 error is means:
The specified resource was not found. This can happen in several
cases. Here are some examples:
when the requested resource (with the provided ID) has never existed
when accessing a calendar that the user can not access
So most likely you are providing the wrong calendar or event id.

Acumatica REST API - Create activity linked to customer

I am trying to programmatically add an activity to a customer entity. I can create both a customer and a note using the API with a PUT, but I cannot figure out how to relate the activity to the customer. I viewed the JSON definition using Postman, but didn't see anything that made sense for relating it to another entity. I tried adding RelatedEntityDescription, but that unsurprisingly did not work.
Here is my JSON body for the PUT (it works but creates an un-linked activity)
{
"Body": {
"value": "message text"
},
"Date": {
"value": "2020-04-22T15:28:00.99-05:00"
},
"Summary": {
"value": "Test message"
}
}
What do I need to add to link it to my customer?
Good day Sreimer
The Table you should be saving to is Note.
It links on BAccount.NoteID and Note.NoteID.
An easy way to test this is to create and save a note on a customers and look for it in Note:
select *
from Note
where NoteText like '%test%';
You just need to specify the RelatedEntityType and RelatedEntityNoteID in your request
{
"Body": {},
"Date": {
"value": "2021-01-06T14:42:03.837-08:00"
},
"RelatedEntityNoteID": {
"value": "01a0c017-df7f-ea11-8175-b9d61cb73193"
},
"RelatedEntityType": {
"value": "PX.Objects.AR.Customer"
},
"Summary": {
"value": "Test Activity 4"
},
"Type" : {
"value" : "M"
}
}

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.

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.