Microsoft Graph webhooks - subscribe to user calendars - microsoft-graph-api

I have a problem with my Microsoft Graph webhook subscriptions to /me/events. What I want to do is to subscribe to all user calendars.
First I have created the new app in https://apps.dev.microsoft.com using my personal Microsoft account.
Then in my app I subscribe to /me/events notifications using access token:
POST https://graph.microsoft.com/beta/subscriptions
{
"changeType": "created,updated",
"notificationUrl": "https://xxxxx.ngrok.io/notification-url",
"resource": "/me/events",
"expirationDateTime": "2018-11-14T09:40:10.933Z",
"clientState": "xxxx-xxxx-xxxx-xxxx"
}
My notificationUrl receives validation request to which my app responds with 200 OK and validation token. After that the POST request returns me my subscription:
{
"#odata.context" : "https://graph.microsoft.com/beta/$metadata#subscriptions/$entity",
"id" : "2773aa4c-e983-4d15-9236-xxxxxxxx",
"resource" : "/me/events",
"applicationId" : "d551ec34-8d44-4cc6-9b88-xxxxxxxx",
"changeType" : "created,updated",
"clientState" : "xxxx-xxxx-xxxx-xxxx",
"notificationUrl" : "https://xxxxx.ngrok.io/notification-url",
"expirationDateTime" : "2018-11-14T09:40:10.933Z",
"creatorId" : "00000000000"
}
This subscription works fine but only for one, default calendar in Outlook. I don't receive any notifications if I create, update events in any other calendars that exists in my account.
What could be the problem here, am I using wrong resource name (/me/events) or this is some limitation for personal accounts in Microsoft Graph?

When you use /me/events you are going to the default Calendar for the user (per the docs). In your case, you would want to enumerate the user's calendars (GET /me/calendars) then subscribe to each one's events collection, using the resource /me/calendars/{calendar-id}/events.

Related

List calendars and events from users

I need to read the calendars and events of two users to create an event for both users.
The documentation says it should be possible.
https://learn.microsoft.com/en-gb/graph/api/calendar-get?view=graph-rest-1.0&tabs=http
GET /users/{id | userPrincipalName}/calendar
This should give me the users default calendar.
I tried this on the graph explorer page (https://developer.microsoft.com/en-us/graph/graph-explorer) and i always get the same error.
{
"error": {
"code": "ErrorItemNotFound",
"message": "The specified object was not found in the store.",
"innerError": {
"date": "2022-09-22T06:40:48",
"request-id": "cc36cb73-348a-4062-a07b-70cf4617e7cc",
"client-request-id": "6932f760-f6b2-5d40-5350-c380917725f2"
}
}
}
I get the same error with calendars, which should give me all calendars. Without the calendar i retrieve the user details, so the id is ok. Any idea or hint why it is not working?
Graph Explorer supports only delegated permission type.
For delegated permissions you can get another user's calendar if another user has shared a calendar with you, or, you have given delegated access to that user.
Resources:
Get calendar
Get shared or delegated Outlook calendar and its events

how to create an encrypted certificate for ms graph subscription requests?

I'm trying to create a subscription to MS Graph for MS Teams chats.
I've been reading through this documentation: https://learn.microsoft.com/en-us/graph/teams-changenotifications-teammembership
The sample POST message looks like this:
POST https://graph.microsoft.com/v1.0/subscriptions
Content-Type: application/json
{
"changeType": "created,deleted,updated",
"notificationUrl": "https://webhook.azurewebsites.net/api/resourceNotifications",
"resource": "/teams/{team-id}/members",
"includeResourceData": true,
"encryptionCertificate": "{base64encodedCertificate}",
"encryptionCertificateId": "{customId}",
"expirationDateTime": "2019-09-19T11:00:00.0000000Z",
"clientState": "{secretClientState}"
}
It's not clear to me how I would create the encryption certificate or the certificateId values
I'm currently googling / poking around in the MS graph docs but if someone could just point me to the right article, I'd appreciate it.
You need to create a certificate on Azure, and store it in a Vault.
Then when you will create the Subscription you will use:
encryptionCertificate property ( certificate that you created )
encryptionCertificateId property ( your own identifier )
Follow these instructions on the GraphAPI doc -> Develop\Use the API\Change notifications -> Notifications with resource data
Managing encryption keys that you need for Notifications
I recommend you to go thru this doc, which is more complete that the example you got.
And don't forget to validate de endpoint! describe in this doc too.
Setup a subscription with resource data
The formal description of these two fields:
Subscription Properties
I hope it helps :)

Using RSC To Access Chat Messages with Microsoft Graph

I am building a Teams chat-bot that looks at the history of messages in the current chat/channel whilst in conversation with the user.
My bot has been granted all the RSC (Resource-Specific Content) Permissions it needs (see image below)
Here is the relevant parts of the manifest:
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.11/MicrosoftTeams.schema.json",
"version": "1.0.0",
"manifestVersion": "1.11",
"id": "bd33f8b1-b593-433c-926e-44a27c1bd94a",
...
"permissions": [
"identity",
"messageTeamMembers"
],
...
"bots": [
{
"botId": "e6d93739-a8ab-412d-a4f6-b6f514a3451a",
"scopes": [
"team",
"personal",
"groupchat"
],
"isNotificationOnly": false,
"supportsFiles": true
}
],
"validDomains": [],
"webApplicationInfo": {
"id": "e6d93739-a8ab-412d-a4f6-b6f514a3451a",
"resource": "https://RscBasedStoreApp",
"applicationPermissions": [
"TeamSettings.Read.Group",
"ChannelMessage.Read.Group",
"TeamSettings.Edit.Group",
"ChannelSettings.ReadWrite.Group",
"Channel.Create.Group",
"Channel.Delete.Group",
"TeamsApp.Read.Group",
"TeamsTab.Read.Group",
"TeamsTab.Create.Group",
"TeamsTab.ReadWrite.Group",
"TeamsTab.Delete.Group",
"Member.Read.Group",
"Owner.Read.Group",
"ChatSettings.Read.Chat",
"ChatSettings.ReadWrite.Chat",
"ChatMessage.Read.Chat",
"ChatMember.Read.Chat",
"Chat.Manage.Chat",
"TeamsTab.Read.Chat",
"TeamsTab.Create.Chat",
"TeamsTab.Delete.Chat",
"TeamsTab.ReadWrite.Chat",
"TeamsAppInstallation.Read.Chat",
"OnlineMeeting.ReadBasic.Chat",
"Calls.AccessMedia.Chat",
"Calls.JoinGroupCalls.Chat",
"TeamsActivity.Send.Chat"
]
}
}
Note: the bot has permission to read messages in chats and channels. Specifically, my problem affects chats and not channels (which I can get messages from fine).
In order to do this, I get a JWT token for the bot account, accessing the Graph API like so:
GraphServiceClient<?> gsc = GraphServiceClient.builder()
.authenticationProvider(u -> mac.getToken())
.buildClient();
Next, I am using the Graph API to pull back these messages. For messages in channels I can do:
gsc.teams("some group id")
.channels("team id")
.messages()
.buildRequest(Collections.emptyList()).get()));
This works fine.
For chats, I am doing something like:
gsc.chats("29:13qY8hmfkJinH9-v7rYKjCNFHYFJXKbjqR-NyzyKzL694npelHJoq5HrVtqJLRYo79OYeHGQq-bhtJM5N-yKXyQ")
.messages()
.buildRequest().get()));
However, this time I get an error from the Graph API:
[Some information was truncated for brevity, enable debug logging for
more details] com.microsoft.graph.http.GraphServiceException: Error
code: Forbidden Error message: Invoked API requires Protected API
access in application-only context when not using Resource Specific
Consent. Visit
https://learn.microsoft.com/en-us/graph/teams-protected-apis for more
details.
GET
https://graph.microsoft.com/v1.0/chats/29:13qY8hmfkJinH9-v7rYKjCNFHYFJXKbjqR-NyzyKzL694npelHJoq5HrVtqJLRYo79OYeHGQq-bhtJM5N-yKXyQ/messages
SdkVersion : graph-java/v5.6.0
I am at a loss to explain why querying channels works fine but querying chats fails.
Any help gratefully appreciated!
This is a protected API and in order to use it you will first need to make a formal request to Microsoft Graph, asking for permissions to use the API without any user interaction
Here is the list of protected APIs. You need to fill this form to get the required permissions.
To request access to these protected APIs, complete the following
request form. We review access requests every Wednesday and deploy
approvals every Friday, except during major holiday weeks in the U.S.
Submissions during those weeks will be processed the following
non-holiday week.
The other option would be to use delegated flow.

Creating a Microsoft Graph webhook subscription to security/alerts fails

When I attempt to create a Microsoft Graph webhook subscription to the security/alerts endpoint, the subscription creation fails with a generic message as shown below. Modifying the resource to 'me/messages' results in a successful webhook subscription created, so this appears to be specific to the security/alerts endpoint. How do I move past this?
The body of the request is as such:
{
"changeType": "created",
"notificationUrl": "https://xxxxxxxxx.azurewebsites.net/api/graphnotifications",
"resource": "security/alerts?$filter=vendorInformation/provider+eq+'ASC'",
"expirationDateTime": "2018-11-15T11:00:00.0000000Z",
"clientState": "secretClientValue"
}
Please use 'updated' for 'changeType'. Security/Alerts uses 'updated' for all new or updated alerts.
Wes, you didn't post the URL that you sent that request to. As per the documentation for Security Alerts.
You can use Microsoft Graph webhooks to subscribe to and receive notifications about updates to Microsoft Graph Security entities.
https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/resources/security-api-overview
On that page, it states posting a request and gives a sample like this
POST https://graph.microsoft.com/v1.0/subscriptions
Content-Type: application/json
{
"changeType": "created,updated",
"notificationUrl": "https://webhook.azurewebsites.net/notificationClient",
"resource": "/me/mailfolders('inbox')/messages",
"expirationDateTime": "2016-03-20T11:00:00.0000000Z",
"clientState": "SecretClientState"
}
https://developer.microsoft.com/en-us/graph/docs/concepts/webhooks
Are you posting that request body to that url?

Fetch events from shared calendar with Office 365 REST API

Loading shared calendar from a user works so far.
However, as soon as you want to load the events, we get the following error message:
ErrorAccessDenied
Access is denied. Check credentials and try again.
The URL looks like this:
https://outlook.office.com/api/v2.0/users/{userName}/calendars/{sharedCalendarId}/calendarView
Query:
{
"query": {
"$select": "Subject,Location,Start,End,IsAllDay,BodyPreview,Extensions",
"$expand": "Extensions($filter=Id eq \"Microsoft.OutlookServices.OpenTypeExtension.custom.string.here\")",
"startDateTime": "2018-07-09T22:00:00.000Z",
"endDateTime": "2018-11-09T23:00:00.000Z"
},
"headers": {
"Prefer": [
"odata.track-changes",
"odata.maxpagesize=200"
]
}
}
The following scopes were set:
"openid",
"profiles",
"offline_access", // for refresh token
"https://outlook.office.com/calendars.readwrite",
"https://outlook.office.com/calendars.read.shared",
"https://outlook.office.com/calendars.readwrite.shared"
The Outlook REST API requests are always performed on behalf of the current user (authenticated user). That's why the endpoint /me/calendars works but users/{userId}/calendars does not. You can not get access to another user's calendar using this API. More information is provided here.
To access the other user's calendar you should switch to Microsoft Graph API. Then you could use the following endpoints:
Using https://graph.microsoft.com/v1.0/
GET /me/calendar/calendarView
GET /users/{id | userPrincipalName}/calendar/calendarView
GET /groups/{id}/calendar/calendarView
Remember to specify permissions for accessing user's calendars.

Resources