I want to create calendar (outlook) events via the microsoft graph api and set some specific response options.
In the (windows) Outlook client I am able to enable/disable
Request Response
Allow new Time Proposals
Allow Forwarding
In the documentation I can only find properties to enable/disable "Request Response" https://learn.microsoft.com/en-us/graph/api/user-post-events? but not the later ones.
The question is how to enable/disable Time Proposals and Forwarding?
I tried setting the sensitivity to "personal", "private" and "confidential" but it didn't help.
You can do that through the extended property DoNotForward. This has the following property definition:
PropertySet: 00020329-0000-0000-C000-000000000046
Name: DoNotForward
Type: Boolean
Here is an example I wrote for this.
Allow time proposal is:
PropertySet:00062002-0000-0000-C000-000000000046
Name: AppointmentNotAllowPropose
Type: Boolean
Using the ms-graph-sdk for dotnet the following code works:
var e = new Event()
{
Subject = "subject",
Start = new DateTimeTimeZone()
{
DateTime = dateTimeTimestamp1,
TimeZone = "Europe/Berlin"
},
End = new DateTimeTimeZone()
{
DateTime = dateTimeTimestamp2,
TimeZone = "Europe/Berlin"
},
SingleValueExtendedProperties = new EventSingleValueExtendedPropertiesCollectionPage()
{
new SingleValueLegacyExtendedProperty
{
Id = "Boolean {00020329-0000-0000-C000-000000000046} Name DoNotForward",
Value = "true"
},
new SingleValueLegacyExtendedProperty
{
Id = "Boolean {00062002-0000-0000-C000-000000000046} Id 0x825A",
Value = "true"
}
}
};
The AppointmentNotAllowPropose is referenced here by id, as setting the value by it's name somehow does not have an effect.
Related
I have an error occurring that I can't seem to find anything about. When I run my code I get the following error. I am not setting oDataType so I assume this is something done by the api itself.
ServiceException: Code: RequestBodyRead Message: The property 'oDataType' does not exist on type microsoft.graph.itemBody'. Make sure to only use property names that are defined by the type or mark the type as open type.
My code is mostly copied from microsoft samples.
var confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithTenantId(tenantId)
.WithClientSecret(clientSecret)
.WithAuthority(new Uri(authority))
.Build();
ClientCredentialProvider authenticationProvider = new ClientCredentialProvider(confidentialClientApplication);
client = new GraphServiceClient(authenticationProvider);
var message = new Microsoft.Graph.Message()
{
Subject = "Test email",
Body = new ItemBody
{
ContentType = BodyType.Text,
Content = "Test email."
},
HasAttachments = false,
ToRecipients = new List<Recipient>()
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = "myemail#mydomain.com"
}
}
}
};
var saveToSentItems = false;
await client.Users[userID].SendMail(message, saveToSentItems).Request().PostAsync();
Any help would be greatly appreciated.
Thank you
I suspect, you're using a older library/build. I remember the related issue and it's fixed last year itself.
Please update it with the latest one , try testing the same and let us know if you can still repro the issue or not.
I want to create a specific class of assignments.
At Graph Explorer,
https://graph.microsoft.com/beta/education/classes/{classId}/assignments
This request works well.
But in my C# code,
var assignInfo = new EducationAssignment
{
DisplayName = "test",
DueDateTime = DateTimeOffset.Parse("2020-09-20T18:00:00Z"),
Instructions = new EducationItemBody
{
ContentType = BodyType.Html,
Content = "hi"
},
Status = EducationAssignmentStatus.Draft,
AllowStudentsToAddResourcesToSubmission = true,
AssignTo = new EducationAssignmentClassRecipient
{
},
Grading = new EducationAssignmentPointsGradeType()
{
MaxPoints = 100
},
CreatedDateTime = DateTimeOffset.Parse("2020-09-20T12:00:00Z"),
AssignDateTime = DateTimeOffset.Parse("2020-09-20T13:00:00Z"),
AssignedDateTime = DateTimeOffset.Parse("2020-09-20T13:00:00Z"),
CloseDateTime = null,
AllowLateSubmissions = true
};
await graphClient.Education.Classes[pClassId].Assignments
.Request()
.AddAsync(assignInfo);
It occured error:
{"Code: 20132\r\nMessage: The content of the request is invalid. Common causes are an invalid Content-Type header or no content in the body.\r\nInner error:\r\n\tAdditionalData:\r\n\tdate: 2020-09-20T07:25:14\r\n\trequest-id: d2181119-9116-4f1d-9ed4-d007e2e406d0\r\n\tclient-request-id: d2181119-9116-4f1d-9ed4-d007e2e406d0\r\nClientRequestId: d2181119-9116-4f1d-9ed4-d007e2e406d0\r\n"}
Why is this happening? I've been thinking and trying all day.
I tried
await graphClient.Education.Classes[pClassId].Assignments
.Request()
.Header("Content-Type", "application/json")
.AddAsync(assignInfo);
But there was the same error.
If only the displayname element was requested, the results were the same.
The Permissions has been dealt with.
EduAssignments.ReadWriteBasic, EduAssignments.ReadWrite.. etc
And the dll(NuGet pakage) is also prepared in beta version.
I referred to this document.
I'm desperate for help..
Thanks.
adding this assignInfo.ODataType = null; fixes the problem.
I am writing a calendar integration and using the Google Calendar api and Outlook Graph api to sync calendar events. I am receiving webhook notifications as changes are made to events, so I need a way to identify that an event in Google and an event in Outlook are the same (or different) events. Theoretically, this should be done with the iCalUId.
However, when I create an event in Google that has an Outlook attendee, the event created in Outlook does not have the same iCalUId as the event in Google.
I created a work-around for this by reading the iCalUId from the attachment sent by Google to Outlook. However, the Outlook event itself still has a different iCalUId than the Google event, which makes it difficult to process future updates.
Conceptually, Outlook is able to update an event (and show it updated on the calendar) when it is updated by Google. So Outlook must be storing some reference to the Google event.
Does anyone know what that reference is and if it is accessible through the Graph API/SDK?
UPDATE
Here is the code I am using to save an event in Google using the Google API/SDK:
var service = await GoogleAuthenticationProvider.GetCalendarService(CALENDAR_CLIENT_ID, CALENDAR_CLIENT_SECRET, CALENDAR_ACCESS_SCOPES, Person.CalendarRefreshToken).ConfigureAwait(false);
var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(Person.TimeZone);
//in google, having the organizer as an attendee causes the organizer to receive notification emails from google- which we don't want, so remove him/her from the attendees
var attendees = Event.Attendees.Where(a => a.Value != Event.OrganizerEmail);
var tmpEvent = new Google.Apis.Calendar.v3.Data.Event
{
Id = ExternalID.IsNullOrEmptyExtension() ? Convert.ToString(Event.ID) : ExternalID,
Start = new EventDateTime
{
DateTime = Event.StartDate,
TimeZone = GetGoogleTimeZoneFromSystemTimeZone(timeZoneInfo.Id)
},
End = new EventDateTime
{
DateTime = Event.EndDate,
TimeZone = GetGoogleTimeZoneFromSystemTimeZone(timeZoneInfo.Id)
},
Summary = Event.Title,
Description = Event.Description,
Attendees = attendees.Select(a => new EventAttendee
{
Email = a.Value,
ResponseStatus = "accepted"
}).ToList(),
GuestsCanInviteOthers = false,
Location = Event.Location,
Recurrence = Event.RecurrenceRule.IsNullOrEmptyExtension() ? new List<string> { } : new List<string> { "RRULE:" + Event.RecurrenceRule }
};
var savedEvent = new Google.Apis.Calendar.v3.Data.Event { };
if (ExternalID.IsNullOrEmptyExtension())
{
EventsResource.InsertRequest insertRequest = service.Events.Insert(tmpEvent, GOOGLE_PRIMARY_CALENDARID);
insertRequest.SendUpdates = EventsResource.InsertRequest.SendUpdatesEnum.All;
savedEvent = await insertRequest.ExecuteAsync().ConfigureAwait(false);
}
else
{
var updateRequest = service.Events.Update(tmpEvent, GOOGLE_PRIMARY_CALENDARID, ExternalID);
updateRequest.SendUpdates = EventsResource.UpdateRequest.SendUpdatesEnum.All;
savedEvent = await updateRequest.ExecuteAsync().ConfigureAwait(false);
}
I am wondering if the /v1.0/me/sendMail has the ability to delay sending an email. In the Outlook client, you can specify that you want your email sent at a later date and time. I've snooped around to see if there is a property that can be set on the message object to indicate this.
Did anyone find a way to get this working? Of course, I could implement something in my software to handle the delayed sending, but why re-create something if it is already there.
You can achieve delayed sending of emails using extended properties. These can be set on the Graph API request payload using the "singleValueExtendedProperties" attribute.
The property to use is PidTagDeferredSendTime which has the ID 0x3FEF and type SystemTime.
The id attribute of "singleValueExtendedProperties" takes different formats depending on the property you are setting.
For the deferred send time you would use SystemTime 0x3FEF.
Example using a HTTP JSON POST Payload:
{
"message": {
"subject": "Meet for lunch?",
"body": {
"contentType": "Text",
"content": "The new cafeteria is open."
},
"toRecipients": [
{
"emailAddress": {
"address": "bob#contoso.com"
}
}
],
"singleValueExtendedProperties":
[
{
"id":"SystemTime 0x3FEF",
"value":"2019-01-29T20:00:00"
}
]
}
}
Example using the Microsoft Graph API client library:
var client = /* Create and configure GraphServiceClient */;
var msg = new Message();
msg.ToRecipients = List<Recipient>();
msg.ToRecipients.Add(new Recipient() {
EmailAddress = new EmailAddress() { Address ="bob#contoso.com" }
};
msg.Subject = "Meet for lunch?";
msg.Body = new ItemBody()
{
Content = "The new cafeteria is open.",
ContentType = BodyType.Text,
};
msg.SingleValueExtendedProperties = new MessageSingleValueExtendedPropertiesCollectionPage();
msg.SingleValueExtendedProperties.Add(new SingleValueLegacyExtendedProperty()
{
Id = "SystemTime 0x3FEF",
Value = DateTime.UtcNow.AddMinutes(5).ToString("o")
});
await client.Me.SendMail(msg, true).Request().PostAsync();
https://gallery.technet.microsoft.com/office/Send-Emails-until-a-9cee20cf
You set the deferred send time extended prop when creating the item.
I have been trying to insert a Google calendar event via Google service account that was created for an app in my dev console, but I am continually getting a helpless 404 response back on the Execute method. In the overview of the dev console I can see that the app is getting requests because there are instances of errors on the calendar.events.insert method. There is no information on what is failing. I need this process to use the Service account process instead of OAuth2 so as to not require authentication each time a calendar event needs to be created.
I have set up the service account, given the app a name, have the p12 file referenced in the project. I've also, gone into a personal calendar and have shared with the service account email address. Also, beyond the scope of this ticket, I have created a secondary app, through an administration account and have granted domain wide access to the service account only to receive the same helpless 404 error that this is now giving.
Error Message: Google.Apis.Requests.RequestError
Not Found [404]
Errors [Message[Not Found] Location[ - ] Reason[notFound] Domain[global]
Any help identifying a disconnect or error would be greatly appreciated.
var URL = #"https://www.googleapis.com/calendar/v3/calendars/testcalendarID.com/events";
string serviceAccountEmail = "createdserviceaccountemailaq#developer.gserviceaccount.com";
var path = Path.Combine(HttpRuntime.AppDomainAppPath, "Files/myFile.p12");
var certificate = new X509Certificate2(path, "notasecret",
X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { Google.Apis.Calendar.v3.CalendarService.Scope.Calendar },
}.FromCertificate(certificate));
BaseClientService.Initializer initializer = new
BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Test App"
};
Google.Apis.Calendar.v3.CalendarService calservice = new Google.Apis.Calendar.v3.CalendarService(initializer);
string timezone = System.TimeZone.CurrentTimeZone.StandardName;
var calendarEvent = new Event()
{
Reminders = new Event.RemindersData()
{
UseDefault = true
},
Summary = title,
Description = description,
Location = location,
Start = new EventDateTime()
{
//DateTimeRaw = "2014-12-24T10:00:00.000-07:00",
DateTime = startDateTime,
TimeZone = "America/Phoenix"
},
End = new EventDateTime()
{
//DateTimeRaw = "2014-12-24T11:00:00.000-08:00",
DateTime = endDateTime,
TimeZone = "America/Phoenix"
},
Attendees = new List<EventAttendee>()
{
new EventAttendee()
{
DisplayName = "Joe Shmo",
Email = "joeshmoemail#email.com",
Organizer = false,
Resource = false
}
}
};
var insertevent = calservice.Events.Insert(calendarEvent, URL);
var requestedInsert = insertevent.Execute();
I had the same problem. The solution was to add an email client, whose calendar event you want to send.
Credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = Scopes,
User = "example_client_email#gmail.com"
}.FromCertificate(certificate));
So I found out that for this to work, You need to make sure that you access the google.Admin account for referencing the service account Client ID of the app you created.
Another thing that helps is making sure the timezone is in the following format "America/Phoenix"
I have now successfully created events through the service account WITHOUT authentication.