Working with Office 365 Groups

Working with Office 365 Groups

Working with Office 365 Groups

Office 365 Groups are a new feature of Office 365. The Microsoft Graph API provides a way to interact with the Office 365 Groups and to browse all the capabilities of each group.

 

To access the Office 365 Groups you can browse the group's entity set of the current tenant to get a list of objects of type Microsoft.Graph.Group, where the group types property contains the value Unified. Here, you can see the corresponding URL, which leverages OData filtering capabilities:

https://graph.microsoft.com/v1.0/groups?

$filter=groupTypes/any(g:%20g%20eq%20’Unified’)

 

Notice any operator applied on the collection property named group types and the OData syntax to represent a kind of predicate. In Listing, you can see an excerpt of the result for the query defined above.

 

LISTING An excerpt of the JSON array providing the groups of type Office 365 Group

{
"value": [
{
"id": "c748625f-ece2-4951-bab7-6e89ad8b6f10",
"description": "Sample Group",
"displayName": "Sample Group",
"groupTypes": [
"Unified"
],
"mail": "samplegroup@PiaSysDev.onmicrosoft.com",
"mailEnabled": true,
"mailNickname": "samplegroup",
"onPremisesLastSyncDateTime": null,
"onPremisesSecurityIdentifier": null,
"onPremisesSyncEnabled": null,
"proxyAddresses": [
"SMTP:samplegroup@PiaSysDev.onmicrosoft.com"
],
"securityEnabled": false,
"visibility": "Public"
}]
}

The result of such a URL query will be a JSON object that represents a collection of Office 365 Groups. You can see the main properties of the Office 365 Group instance, including the id, displayName, mail address, visibility, and so on.

 

As with any group, you can access a specific group by appending the id value after the group's collection URL.

 

Moreover, every Office 365 Group provides a set of navigation properties to browse the photo for the group, the calendar, the conversations, the files, and the group’s members. For example, if you want to access the photo of the group, here is the sample URL to use:

https://graph.microsoft.com/v1.0/groups/<group-id>/photo/$value

 

To access the calendar of a group, you just need to make an HTTP GET request for a URL like the following:

https://graph.microsoft.com/v1.0/groups/<group-id>/calendar

 

You will get back an object of type Microsoft.Graph.Calendar, which can be used exactly like any other calendar in the Microsoft Graph. You can refer to the section “Consuming mail, contacts, and calendars” earlier in this blog for further details about how to manage calendars, events, and meetings.

 

To access a group’s conversations, there is a straightforward navigation property called conversations, which can be used to get a list of all the conversations or to access a specific conversation by id. 

 

LISTING  An excerpt of the JSON representation of a conversation within an Office 365 Group

{
"id":
"AAQkADdkNjZjMDUwLTA1ZmItNGRiNS04ZWI5LTdjOTQwZTk1MDZiNAAQABzdWzBNd3VKtWsenlfeLc
"topic": "The new group Sample Group is ready",
"hasAttachments": true,
"lastDeliveredDateTime": "2015-12-03T12:01:30Z",
"uniqueSenders": [
"Sample Group"
],
"preview": "Welcome to the group Sample Group."
}

The group’s members can be queried by invoking the member's navigation property, like in the following URL:

https://graph.microsoft.com/v1.0/groups/<group-id>/members

 

You can subscribe to or unsubscribe from email notifications by using the subscribeByMail and the unsubscribeByMail actions, and you can manage the group as a favorite by using the addFavorite and remove favorite methods.

 

LISTING The HTTP DELETE request to delete a file in OneDrive for Business

DELETE /v1.0/me/drive/items/01MDKYG3G3MLQJYQ7CUZG3GQRA7MBBY57D HTTP/1.1
Authorization: Bearer eyJ0...
Host: http://graph.microsoft.com
Content-Length: 0
Content-Type: application/json

 

The response will be an HTTP Status Code with a value of 204 (No Content), which implies a successful deletion of the target file or folder.

 

Searching within a drive

In real-life scenarios, users have a lot of files in their OneDrive for Business, especially considering the huge amount of data that every user is allowed to store there.

 

Thus, browsing the folders and files is not always the best way to find content. Luckily, OneDrive for Business is based on Microsoft SharePoint Online, which provides a powerful search engine that can be used to search OneDrive for Business.

 

Searching for content, whether files or folders, is straightforward. You just need to target an object of type Microsoft.Graph.driveItem, which can be the root folder or any subfolder, and invoke the microsoft.graph.search (or search) function providing a search query text.

 

In Listing, you can see a sample search request that looks for any file or folder containing the word “sample.”

 

LISTING The HTTP GET request to search for files or folders containing the word “sample”

GET /v1.0/me/drive/root/microsoft.graph.search(q='sample') HTTP/1.1
Authorization: Bearer eyJ0...
Host: http://graph.microsoft.com
Content-Length: 0
Content-Type: application/json
The response will look like the excerpt in Listing and will include both files and folders matching the search criteria.
LISTING An excerpt of the JSON array returned by invoking the search operation for the root folder of the OneDrive for Business of the current user
{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#driveItem",
"value": [
{
"@odata.type": "#microsoft.graph.driveItem",
"createdBy": {
"user": {
"displayName": "Thesis Scientist"
}
},
"createdDateTime": "2015-07-10T17:13:04Z",
"folder": {
"childCount": 0
},
"id": "01MDKYG3G3MLQJYQ7CUZG3GQRA7MBBY57D",
"lastModifiedBy": {
"user": {
"displayName": "Thesis Scientist"
}
},
"lastModifiedDateTime": "2015-07-10T17:13:04Z",
"name": "Sample Share",
"searchResult": {},
"size": 0,
"webUrl": "https://sharepoint-camp_com/Documents /Sample%20Share"
},
{
"@odata.type": "#microsoft.graph.driveItem",
"createdBy": {
"user": {
"displayName": "Thesis Scientist"
}
},
"createdDateTime": "2015-09-09T04:25:26Z",
"file": {},
"id": "01MDKYG3EIHAILISRHVBDJQVXKTI3LGHVA",
"lastModifiedBy": {
"user": {
"displayName": "Thesis Scientist"
}
},
"lastModifiedDateTime": "2013-07-11T00:23:31Z",
"name": "Office 365 Sample File.pdf",
"searchResult": {},
"size": 426620,
"webUrl": "https://sharepoint-camp_com/Documents /Sample%20Share/Office%20365%20Sample%20File.pdf"
},
...
]
}

Note that the search engine will not only search for files and folders with matching names but also will search the content inside files, as happens with the classic Microsoft SharePoint search engine.

 

Sharing files and folders

Sharing a file or a folder is another useful capability that is available through the Microsoft Graph API. Whenever you want to share an object of type Microsoft.Graph.drive them, you can invoke the microsoft.graph.createLink (or createLink) action using an HTTP POST method.

 

The create Link action accepts two input parameters: type A string parameter that defines whether the item will be shared for the view, which means read-only; for edit, which means read and write;

 

or for embed, which creates an embeddable link scope Defines the scope of the action link and can have a value of the organization, which means that the target users will have to access the resource with an organizational account; or anonymous, which means that the link will be accessible anonymously. 

 

These parameters have to be provided through a JSON serialized object. In Listing, you can see a sample file sharing request.

 

LISTING The HTTP POST request to share a file for anonymous viewing

>POST
/v1.0/me/drive/items/01MDKYG3AUTHKROIRYDVHIHLBSZQU7ZNUE/microsoft.graph.createLink
HTTP/1.1
Authorization: Bearer eyJ0...
Host: http://graph.microsoft.com
Content-Length: 0
Content-Type: application/json
{
"type": "view",
"scope": "anonymous"
}

The response is illustrated in Listing and represents an instance of an object of type Microsoft.Graph.Permission.

 

LISTING An excerpt of the JSON returned by invoking the microsoft.graph.the createLink operation for a driveItem

{
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#permission",
"@odata.type": "#microsoft.graph.permission",
"id": "N0JCQTQ2MzItRTAxQi00RDlBLUFEMkEtNEZCMTZDRkFDODM3",
"roles": [
"read"
],
"link": {
"type": "view",
"webUrl":
"https://piasysdev-my.sharepoint.com/_layouts/15/guestaccess.aspx?
guestaccesstoken=OQ7bQd8
WRvu0OTxu2%2fuKi6KoHB%2bidQgE6tZVGnoC35c%3d&docid=2_0e34e1f4b0e5640388180ae9a6e49f
}
}

The sharing link will be available in the web URL property of the link object.

 

Security groups

Through the Microsoft Graph API, you can also access groups, including both security groups, synchronized across premises using directory synchronization tools, and the new Office 365 Groups, which are also called Unified Groups from an Office 365 perspective. 

However, you can play with the group types of property, which has a null value for security groups and a value of Unified for any Office 365 Group. 

 

To access the members of a specific group, you can add the member's keyword at the end of the single group endpoint URL.

 

Consuming mail, contacts, and calendars

Now that you have learned how to consume users, security groups, and licenses, you are ready to leverage the other APIs—for example, those for Microsoft Exchange Online, which is another common and useful scenario.

 

Thanks to the unified API model, the base URL remains the same; you just have to change the relative URL of the service endpoint. The personal emails of the current user are available through the following base URL: https://graph.microsoft.com/v1.0/me/Messages

 

Mail messages

As already stated, to access the current user’s mailbox, you can query the https://graph.microsoft.com/v1.0/me/Messages URL.

 

The result will be an array of JSON objects of type Microsoft.Graph.Message or of type Microsoft.Graph.EventMessage, which are the email messages and the event-related messages in the current user’s mailbox, regardless of the folder in which they are stored. 

 

It is interesting to notice that by default, the mail service will do output paging and, unless you specify something different in the OData query sent to the service, the default page size will be 10 items per page.

 

At the beginning of the JSON answer, you will find a property with name @odata.nexLink that contains the URL to access the next page of results, and this kind of “next page” link will be available in any requested page.

 

As a result, developers are obliged to do paging, which is a good habit but unfortunately is not always common practice.

 

Moreover, you can see that each message provides well-known information like subject, sender, recipients, content, parent folder Id, and so on. One fundamental piece of information for each message is the Id property.

 

By appending a specific message Id at the end of the path of the message, you can access that specific message item directly.

 

The response will be a JSON object of type Microsoft.Graph.Message with the same properties that were available for each message within the list of messages.

 

Because we are using the OData protocol to query the Microsoft Graph API, we can also use the standard protocol’s syntax to project a subset of properties or to partition the results.

 

For example, imagine that you want to retrieve just the Id, Subject, From, and To Recipients properties of the current message. In Listing, you can see the HTTP GET request to achieve this result, which will target the following URL:

https://graph.microsoft.com/v1.0/me/messages/AAMk...AA=?
$select=Id,Subject,From,ToRecipients
LISTING The HTTP GET request for a subset of properties for a specific email message
GET /v1.0/me/messages/AAMk...AA=?$select=Id,Subject,From,ToRecipients HTTP/1.1
Authorization: Bearer eyJ0...
Host: http://graph.microsoft.com
Content-Type: application/json
Content-Length: 31

In Listing, you can see the response that you should get back.

 

LISTING The JSON response for a projection of properties of a specific email message

{
"@odata.context":
"https://graph.microsoft.com/v1.0/<tenant>/$metadata#users('paolo.
pialorsi%40sharepoint
-http://camp.com')/Messages/$entity", "@odata.type": "#Microsoft.Graph.Message", "@http://odata.id": "users/paolo.pialorsi%40sharepoint-
http://camp.com/MeNzAwL WFkZGExY2M5NDRlZQBGAAAAAAAENAAB VRa8oaXCdnl9HAAIQ3Vk_AAA%3D",
"@odata.etag": "W/\"CQAAABYAAABrFd4C2tvVRa8oaXCdnl9HAAJVc9Lf\"", "Id":
"AAMkADU4Zjk3ZTQzLWFjMDctNDM5Mi04NzAwLWFkZGExY2M5NDRlZQBGAAAAAACIOUtE7VENSpDAypZBE Q3Vk_AAA=",
"Subject": "This is a sample message!",
"From": {
"EmailAddress": {
"Address": "someone@contoso.com",
"Name": "someone@contoso.com"
}
},
"ToRecipients": [
{
"EmailAddress": {
"Address": "paolo.pialorsi@sharepoint-camp.com",
"Name": "Thesis Scientist"
}
}
]
}

 

If you want to filter all the messages in the current user’s inbox based on a specific subject value.

 

Sending an email message by using the Microsoft Graph API is also a simple task. You just need to make an HTTP POST request with the JSON object representing the message to send and targeting the URL of the list of messages to store the message as a draft. In Listing, you can see the HTTP POST request to achieve this result.

 

LISTING The HTTP POST request to save a draft of a new email message

POST /v1.0/me/messages HTTP/1.1
Authorization: Bearer eyJ0...
Host: http://graph.microsoft.com
Content-Length: 383
Content-Type: application/json
{
"Subject": "Sample email from Microsoft Graph API",
"Body": {
"ContentType": "HTML",
"Content": "Hey! This email comes to you from the <b>Microsoft Graph API</b>!"
},
"Importance": "High",
"ToRecipients": [
{
"EmailAddress": {
"Address": "Thesis@gmail.com.com"
}
}
]
}

 

The HTTP response that you will get back will be the JSON representation of the just-saved draft message. In the message object, you will see the IsDraft property with a value of true.

 

To send that message, you will need to invoke the send action, which can be addressed by appending the send keyword at the end of the URL of the message and using an HTTP POST method. 

 

LISTING The HTTP POST request to send a draft email message

POST /v1.0/me/messages/AAMk...AA=/send HTTP/1.1

Authorization: Bearer eyJ0...

Host: http://graph.microsoft.com

Content-Length: 0

 

 

Contacts

The current user’s contacts are another useful capability that is available through the new Microsoft Graph API. To consume the contacts, you have to make an HTTP GET request against the following URL:

 

 https://graph.microsoft.com/v1.0/<user>/contacts In Listing, you can see an excerpt of the resulting JSON response, which represents an array of objects of type Microsoft.Graph.Contact.

 

LISTING An excerpt of the HTTP response that enumerates the organizational or personal contacts in a tenant

{
"@odata.context":
"https://graph.microsoft.com/v1.0/$metadata#users('paolo.pialorsi%40sharepoint-
http://camp.com')
/contacts",
"value": [
{
"@odata.etag": "W/\"EQAAABYAAABrFd4C2tvVRa8oaXCdnl9HAAIQ4ll9\"", "id":
"AAMkADU4Zjk3ZTQzLWFjMDctNDM53XCjAAA=",
"createdDateTime": "2015-09-06T08:41:30Z",
"lastModifiedDateTime": "2015-09-06T08:41:30Z",
"changeKey": "EQAAABYAAABrFd4C2tvVRa8oaXCdnl9HAAIQ4ll9",
"categories": [],
"parentFolderId":
"AAMkADU4Zjk3ZTQzLWFjMDctNAypZBEd4C2tvVRa8oaXCdnl9HAAAAAAEPAAA=",
"birthday": null,
"fileAs": "Green, Mike",
"displayName": "Mike Green",
"givenName": "Mike",
"initials": null,
"middleName": null,
"nickName": null,
"surname": "Green",
"title": null,
"yomiGivenName": null,
"yomiSurname": null,
"yomiCompanyName": null,
"generation": null,
"emailAddresses": [
{
"name": "Mike Green",
"address": "mike.green@contoso.com"
}
],
"imAddresses": [],
"jobTitle": null,
"companyName": null,
"department": null,
"officeLocation": null,
"profession": null,
"businessHomePage": null,
"assistantName": null,
"manager": null,
"homePhones": [],
"businessPhones": [],
"homeAddress": {},
"businessAddress": {},
"otherAddress": {},
"spouseName": null,
"personalNotes": null,
"children": []
},
...
]
}

The structure of contact is defined in the metadata XML document for the Microsoft Graph API. You can see there is an Id property, which can be used to retrieve a specific contact instance directly.

 

Moreover, there are all the common properties for contact, like displayName, email addresses, companyName, and so on.

 

You can also browse users’ various contact folders by querying the contact folders navigation property of an object of type Microsoft.Graph.User. Every contact folder can be accessed by Id, and you can browse its contacts through the contacts navigation property.

 

You can even add contacts or contact folders by making an HTTP POST request against the target collection and providing the JSON representation of the object to create.

 

Calendars and events

Another common use case is the consumption of calendars and events, which are available through a user-oriented set of URLs.  For example, in Listing, you can see the JSON representation of the default calendar for the current user.

 

LISTING An excerpt of the HTTP response that represents the default calendar of the current user

{
"@odata.context":
"https://graph.microsoft.com/v1.0/<tenant>/$metadata#users('paolo.
pialorsi%40sharepoint
"@odata.type": "#Microsoft.Graph.Calendar",
"@http://odata.id": "users/paolo.pialorsi%http://40sharepoint-camp.com/Calendar",
"Id":
"AAMkADU4Zjk3ZTQzLWFjMDctNDM5Mi04NzAwLWFkZGSpDAypZ
d4C2tvVRa8oaXCAAA=", "Name": "Calendar",
"ChangeKey": "axXeAtrb1UWvKGlwnZ5fRwACEOJhrw==",
"Color": "LightGreen"
}

 

The object is a JSON serialization of type Microsoft.Graph.Calendar, which is made of a few properties like Name, Color, and Id. If you invoke the calendars entry point, you will get back an array of objects of type Microsoft.Graph.Calendar.

 

Once you have a calendar, regardless of whether it is the default calendar or a secondary calendar, you can access the events of a specific time and date interval by invoking the calendarView navigation property through an HTTP GET request and providing a couple of query string arguments to declare the startDateTime and the endDateTime in UTC time format.  

 

As you can see, the response includes all the typical information for an event, like Subject, Body, Start and End dates (including their time zone), ShowAs, Attendees, Responses,

 

Organizer, and so on.

You can also access the entire list of events for the current user by invoking the events navigation property of the current calendar or of the current user through an HTTP GET request. The events navigation property will give you back a JSON array of Microsoft.Graph.Event objects. 

 

As with email messages, discussed in the previous section, you can add, update, or delete calendar events by leveraging the various HTTP verbs. 

 

LISTING  The HTTP request to add a new event to the current user’s default calendar

POST /v1.0/me/calendar/events HTTP/1.1
Authorization: Bearer eyJ0...
Host: http://graph.microsoft.com
Content-Length: 599
Content-Type: application/json
{
"Subject": "Sample meeting create via Microsoft Graph API",
"Body": {
"ContentType": "HTML",
"Content": "The <b>Microsoft Graph API</b> really rock!"
},
"start": {
"@odata.type": "#microsoft.graph.dateTimeTimeZone",
"dateTime": "2015-12-22T16:30:00.0000000",
"timeZone": "UTC"
},
"end": {
"@odata.type": "#microsoft.graph.dateTimeTimeZone",
"dateTime": "2015-12-22T17:00:00.0000000",
"timeZone": "UTC"
},
"Attendees": [
{
"EmailAddress": {
"Address": "someone@contoso.com",
"Name": "Thesis Scientist"
},
"Type": "Required"
}
],
"Location": {
"DisplayName": "Headquarters"
},
"ShowAs": "Busy",
}

 

The HTTP response will confirm that the event has been created by providing an HTTP Status Code with a value of 201 (Created). If you want to update an existing event, you can make an HTTP PATCH request, targeting that event by Id and sending the updated properties as a JSON object.

 

For example, in Listing, you can see how to update the Subject property of the just-created event.

 

LISTING The HTTP request to update an existing event in the current user’s default calendar

PATCH /v1.0/me/calendar/events/AAMkADU... HTTP/1.1
Authorization: Bearer eyJ0...
Host: http://graph.microsoft.com
Content-Length: 79
Content-Type: application/json
{
"Subject": "Sample meeting create via Microsoft Graph AP – Updated!"
}

 

The HTTP response will confirm the successful update by providing an HTTP Status Code with a value of 200 (OK) and providing the JSON serialization of the updated event in the response body. Last, if you want to delete an event from a calendar, you can use the HTTP DELETE method, targeting the event URL.

 

The response will be an HTTP Status Code 204 (No Content), meaning that the event has been deleted. Under the cover, Microsoft Exchange Online will handle all the email notifications like sending invitations, updates, and event cancellations.

 

It is interesting to note that the same REST-based techniques used for managing single events can be used to manage calendars. For example, you can create, update, or delete a secondary calendar by targeting the collection:

https://graph.microsoft.com/v1.0/me/calendars

 

This is a powerful capability that enables you to create custom software solutions that can completely handle messages, contacts, calendars, and events via REST.

 

Event invitations

Another common scenario is to manage invitations for events sent to the current user by third parties. In Microsoft Exchange Online, any meeting invitation will automatically be placed in the target user’s default calendar, as happens on-premises.

 

Thus, to access an invitation, you just need to target the specific calendar event object that you want to manage by providing the Id of the object. 

 

LISTING An excerpt of the JSON object representing a meeting request the current user has received

{
"@odata.context":
"https://graph.microsoft.com/v1.0/$metadata#users('thesis%40sharepoint-
http://camp.com')
/Calendar/Events/$entity",
"@odata.type": "#Microsoft.Graph.Event",
"@http://odata.id":
"users/paolo%http://40PiaSysDev.onmicrosoft.com/Calendar/Events/AAMkADU4Zjk3ZTQzLWFjMDctN
zAwLWFkZGExY2M5NDRlZQBGAAAAAACIOUtE7VENSpDAypZBE6ONBwBrFd4C2tvVRa8oaXCdnl9HAAAAAAE
C2tvVRa8oaXCdnl9HAAIQ3Xh2AAA%3D",
"Id":
"AAMkADU4Zjk3ZTQzLWFjMDctNDM5Mi04NzAwLWFkZGExY2M5NDRlZQBGAAAAAACIOUtE7VENSpDAypZ
d4C2tvVRa8oaXCdnl9HAAAAAAEOAABrFd4C2tvVRa8oaXCdnl9HAAIQ3Xh2AAA=",
...
"Importance": "Normal",
"HasAttachments": false,
"start": { "@odata.type": "#microsoft.graph.dateTimeTimeZone",
"dateTime": "2015-12-22T16:30:00.0000000",
"timeZone": "UTC"
}, "end": {
"@odata.type": "#microsoft.graph.dateTimeTimeZone",
"dateTime": "2015-12-22T17:00:00.0000000",
"timeZone": "UTC"
},
...
"ResponseStatus": {
"Response": "not responded",
"Time": "0001-01-01T00:00:00Z"
},
...
}

As you can see highlighted in bold text, there are Id and ResponseStatus properties, together with the rich set of properties defining the event. If the ResponseStatus property has a value of not responded for the property with name Response, it means that the meeting request is pending response.

 

To accept the meeting request, you can make an HTTP POST request targeting the event URL and appending the accept operation to the URL. The ResponseStatus property of the target event will assume a value of Accepted for the property with name Response, and the Time property will assume the value of the date and time when you accepted the meeting request.

 

To decline a meeting request, the operation to append to the URL of the event is decline. To give a tentative answer, you can append the tentatively accept operation to the URL of the event.

 

Regardless of whether you accept, decline, or tentatively accept the meeting request, you will have the option to provide to the meeting organizer a response message that will be provided to the REST API as a JSON object in the body of the request. 

 

LISTING The HTTP request to accept a meeting request, providing a comment to the meeting organizer

POST /v1.0/me/calendar/events/AAMkADU.../accept HTTP/1.1
Authorization: Bearer eyJ0...
Host: http://graph.microsoft.com
Content-Length: 59
Content-Type: application/json;charset=utf-8;odata=minimalmetadata
{
"Comment": "Sure, I'm looking forward to meet you!"
}

The HTTP response will confirm the successful response by providing an HTTP Status Code with a value of 202 (Accepted).

 

Summary

In this blog, you learned about the Microsoft Graph API: its architecture and the overall goal of having a unified set of API. Moreover, you learned how to consume services related to users and groups in the Office Graph.

 

You explored how to consume Exchange Online– related services to browse email messages, send a new message, and reply to a received message.

 

You also saw how to query and manage calendars and contacts. You learned how to query, update, and manage files and folders in OneDrive for Business. Last, you explored how to browse the new Office 365 Groups and their content.

 

The information provided in this and the following blog enables you to consume the Microsoft Graph API from any device and using any development platform as long as it supports the capability to fire HTTP requests and to serialize/deserialize JSON objects.

Recommend