Thursday, December 31, 2020

Add Microsoft Teams members in bulk

The Microsoft Graph team recently released a new way of adding multiple users to a Microsoft Teams team using a single request. The approach is straight forward and error-tolerant as it provides detailed information about which users could and could not be added to the team. This is what the new API looks like:

POST https://graph.microsoft.com/beta/teams/{team-id}/members/add

As you can see from the example above, the API is only available as a beta endpoint. Microsoft Graph beta APIs are subject to change. Hence, you should avoid using this endpoint in production applications. Have a look at the official Microsoft Graph documentation for more information.

The example below shows how to add two users to a team within one single request. The first user doesn’t exist in the tenant, but the second one is correct. In this case, the API returns an exception message for the first user, adds the second user to the team as expected and returns 207 as HTTP status code. However, if there are no error, the API returns 200 as HTTP status code and adds all users as expected. Currently, adding many users to a team is only possible by executing multiple requests which slows down the process. This new approach will be my favorite way of creating membership in a team once this API reaches GA.

POST https://graph.microsoft.com/beta/teams/{team-id}/members/add
{
   "values":[
      {
         "@odata.type":"microsoft.graph.aadUserConversationMember",
         "roles":[
            
         ],
         "user@odata.bind":"https://graph.microsoft.com/beta/users('123a3...')"
      },
      {
         "@odata.type":"microsoft.graph.aadUserConversationMember",
         "roles":[
            "owner"
         ],
         "user@odata.bind":"https://graph.microsoft.com/beta/users('96feb...')"
      }
   ]
}

This is what the response looks like:

{
   "@odata.context":"https://graph.microsoft.com/beta/...",
   "value":[
      {
         "@odata.type":"#microsoft.graph.aadUserConversationMemberResult",
         "userId":"123a3fb6-d598-482f-9c63-f124a537cf3c",
         "error":{
            "code":"NotFound",
            "message":""
         }
      },
      {
         "@odata.type":"#microsoft.graph.aadUserConversationMemberResult",
         "userId":"96feb819-e305-4fc5-99fe-6900c44d0678",
         "error":null
      }
   ]
}

The built-in error management increases the value of this new approach. I am looking forward to working with this API in the future. However, it is worth it to test this new endpoint with large amount of data and check its behavior. Thanks Microsoft Graph team for this Christmas gift. I am looking forward to seeing what the future holds for Microsoft Graph. Right now, I love to work with the Graph endpoints 💛

I hope it helps!
Thanks for reading my blog post.
I wish you all a happy, healthy, and successful 2021 🥳

Tuesday, November 24, 2020

Speaking at Valo Online Summit APAC 2020

I'm looking forward to speaking at Valo Online Summit APAC 2020 on November 25-26, 2020.

Valo is hosting a digital get-together by bringing all the Valo partners together for the very first Valo Online Summit APAC on November 24th – 26th 2020! This Summit is a three-day get-together where the Valo Partner Community meets to delve further into the opportunities and future of Digital Workplace Business. 


I will contribute to this very special event with two sessions:

- Get the latest about Valo Teamwork
- Creating consistent Microsoft Teams teams using Valo Teamwork

I am very happy to be part of the speakers team! Let's get in touch if you're also going to participate in this event!

Event information:

Sunday, November 1, 2020

Speaking at Digital Workplace Summit 2020

I'm looking forward to speaking at Digital Workplace Summit 2020 on November 3, 2020.

The Digital Workplace Summit (#DWSC20) by Communardo is a conference about digital workplace and enterprise collaboration. This digital event offers more than 30 sessions presented by national and international speakers. I posted below my session's description:

"In times of cloud-based software development, a computer program newly introduced to the market can be outdated within a few months. The constant further development and maintenance of a software is therefore very important in order to remain the right tool for the users needs.

In this presentation I would like to share with you experiences from my private life. It surprised me personally how backward some companies are with their tools and what negative impact this has on end customers.

But there is a better way: Valo offers a complete solution for different user problems of the digital workplace. I'll give you an overview of all Valo products (Intranet, Teamwork, Connect and Ideas) and show you how Valo is working continuously to provide quality solutions for Microsoft 365 and the end users."

I am very happy to be a part of the speakers team! Let's get in touch if you're also going to participate in this event!

Event information:

Home Page in German

Monday, October 26, 2020

Microsoft Graph API to create a team is now in GA and supports a new permission level

The Microsoft Graph API to create a team directly without first creating a group has been in GA since September 2020 🥳 If you have been using POST https://graph.microsoft.com/beta/teams to create a Microsoft Teams team, I'd highly recommend you to use POST https://graph.microsoft.com/v1.0/teams.

The beta/teams API was for a long time the only option to create a team without first having to create a group and then creating a team from the group. In many cases, there is no way around a beta API, but if production APIs are available you should consider replacing it immediately. You must be aware that all APIs under the /beta version in Microsoft Graph are subject to change. Basically, Microsoft can apply changes to /beta APIs that might break your solution.

The example below shows a minimal request to create a team. However, the request can also contain channels, tabs, settings, apps etc.

{
   "template@odata.bind":"https://graph.microsoft.com/v1.0/teamsTemplates('standard')",
   "displayName":"My Sample Team",
   "description":"My Sample Team’s Description"
}

Moreover, since October 2020 the POST /teams API supports a new permission level that allows an application to create teams on behalf of a signed-in user and without a signed-in user.
  • Team.Create (delegated permission)
  • Team.Create (application permission)

Previously, an application must use Group.ReadWrite.All to create a Microsoft Teams team. However, this permission level is very comprehensive and should be avoided whenever possible since it allows the application to create groups/teams, read all group/team properties and memberships, update group/team properties and memberships as well as delete groups/teams. Additionally, it can also be used to read and write group calendar and conversations.

Check out the links below for more information about the POST /teams API:


Wednesday, September 30, 2020

Quick Tip: Avoid limitations when reading SharePoint list items using Microsoft Graph

Microsoft introduced in latest version of CSOM a new tenant property Tenant.DisableCustomAppAuthentication which can be used to disable the capability to grant permissions to app authentication in SharePoint. Unfortunately, new Office 365 tenants have this property set to true by default. I'm not sure if that is a glitch, a bug or intentional. Does Microsoft want us to use Graph instead of SharePoint REST in the future? Anyway, from now on I want to use Graph whenever possible.

I’m developing a Microsoft Teams bot currently which uses SharePoint REST to retrieve data from SharePoint lists, create webhooks etc. Since accessing SharePoint lists and sites is already possible from Microsoft Graph we decided internally to replace the existing SharePoint REST implementation with Graph APIs. Unfortunately, I faced a limitation while retrieving data from a SharePoint list which I want to share with you in this blog post.

The goal

I tried to retrieve a SharePoint list item based on its ID. Along with that, I also tried to read additional content such as the item’s fields. This is what the request looks like:

https://graph.microsoft.com/v1.0/sites/1b3c1c82-8d58-4348-b13f-02898a1c662f/
lists/221395e9-cfca-4ac6-ba33-8b678fbc7836/items/407
?$select=Id&$expand=Fields($select=Title,_ModerationStatus,_ModerationComments)

The limitation

I was retrieving data from a SharePoint list which has content approval settings turned on. During my tests, if I tried to read those items that have an approval status other than Approved (e.g.: Rejected or Pending), the API threw the following error:

System.Exception: {
   "error":{
      "code":"itemNotFound",
      "message":"The specified list was not found",
      "innerError":{
         "date":"2020-09-30T14:33:44",
         "request-id":"56d110a8-4b07-4f37-857d-0dff276742bd",
         "client-request-id":"56d110a8-4b07-4f37-857d-0dff276742bd"
      }
   }
}

This error message is definitely misleading since I was able to retrieve other items from the same list.

The workaround

By turning the content approval settings off, I was able to retrieve all items from that list without limitations. However, that wasn’t the solution I was looking for 😀 I tried the same request using the Microsoft Graph Explorer and succeeded. I ended up with the conclusion that the API permission Sites.Manage.All was missing from my AAD app configurations. According to this Microsoft Graph documentationSites.Read.All should be enough to read SharePoint list items. Anyway, after adding the missing permission to my AAD app, I was finally able to read all list items from that list.

I hope it helps!

Saturday, August 1, 2020

Simplifying Proactive Messaging in Microsoft Teams with Microsoft Graph's new API permissions

Proactive Messaging enables you to send notifications in Microsoft Teams without user interaction. Basically, a user or team doesn’t need to interact with the bot to receive its notifications. However, this functionality requires the bot to be installed as a personal app or in a team that the user is a member of. Otherwise, the bot doesn’t have the needed information to proactively contact the user.

There has already been guidance explaining how to combine Microsoft Teams with Microsoft Graph to fulfill the installation requirement. Previously, this process had to be executed manually or programmatically using Graph permissions such as User.ReadWrite.All or Directory.ReadWrite.All that allow any application to be installed. In case of users installing the app manually to receive bot notifications, the proactive concept was no longer complete.

The table turns and the process becomes simpler! Microsoft Graph API introduces two new application permissions TeamsAppInstallation.ReadWriteSelfForUser.All and TeamsAppInstallation.ReadWriteSelfForTeam.All. Those new scoped API permissions allow a Teams app to read, install, upgrade, and uninstall ITSELF for any user/team, without a signed-in user 💛 How cool is that!!! This is how it looks in Azure AD:

To use these new permissions, add a webApplicationInfo key to your team’s app manifest. It must include your Azure AD app ID and the resource URL for the app. Ensure your Azure AD app has the application permission that will fulfill your requirement. E. g.: TeamsAppInstallation.ReadWriteSelfForUser.All if you want to manage notifications for users. This is how webApplicationInfo looks:

"webApplicationInfo": {
  "id":"692107eb-eca3-45da-b81b-e336c762d5e4",
  "resource":"api://692107eb-eca3-45da-b81b-e336c762d5e4"
}

Microsoft has also provided detailed information about the usage of this new approach which is still in public preview. Check out this documentation for more information.

I gave this new approach a try with a bot I've been developing at my company and must say that it works very well. Thanks for the Microsoft Graph Teams team for providing us with these two new application permissions 💛 

Monday, July 13, 2020

New approach to manage membership of Microsoft Teams using Microsoft Graph Teams API

I am so proud of the Microsoft Graph Teams team 💛 It took a while, but the MS Graph Teams team released a new approach to manage Teams membership directly from a dedicated Graph teams API 😯

Background

Currently, changes made to the team’s membership had to be made to the Microsoft 365 group backing a team via the Microsoft Graph API “groups/members” / “groups/owners”. Those membership changes don’t apply immediately to the team and must be synced to the Teams service in order for newly added users to access the team. Unfortunately, the sync mechanism can take up to 24 hours according Microsoft. From my experience, it can take even longer.

The new approach

New teams Graph APIs have been introduced in order to remove the dependency on the group Graph API. Basically, it is no longer required to use group Graph APIs to manage the Teams membership since the new beta/teams/{teamId}/members API is available and it supports CRUD operations!!!

Those APIs support both, delegated and applications permissions 🥳

List all team members and owners

You can use this API to retrieve all members and owners of a TEAM within the same call 😯 That would be perfect if this API would support pagination!!! ATM, this is a known limitation! However, in many cases it might improve performance since you only need one call to retrieve owners and members of a team instead of different calls to first retrieve the group and then retrieve the owners/members. As far as I have tested, this API returns up to 100 users within one request. This is how the request to retrieve all owners and members looks:

GET https://graph.microsoft.com/beta/teams/{teamsId}/members

Check out the corresponding Microsoft Graph documentation for more information! (List all team members and owners)

Add a user

It will add users immediately (always happend during my tests) to the team or return a corresponding error code if the adding process fails. This is a great improvement since the sync delay issue between group and team will no longer be an issue as described previously. This is what the request to add new users to the team looks like:

POST https://graph.microsoft.com/beta/teams/{teamsId}/members

{
   "@odata.type": "#microsoft.graph.aadUserConversationMember",  
   "roles": [""],
   "user@odata.bind": "https://graph.microsoft.com/beta/users/666a3fb6-d598..."  
}

Check out the corresponding Microsoft Graph documentation for more information! (Add members or owners to a team)

Update a user

This API updates the user’s role in a team and is only supported on private channels. For instance, you can use this API to promote an user from member to owner:

PATCH https://graph.microsoft.com/beta/teams/{id}/channels/{id}/members/{id}

{
   "@odata.type": "#microsoft.graph.aadUserConversationMember",
   "roles": ["owner"]
}

Check out the corresponding Microsoft Graph documentation for more information! (Update team members or owners)

Delete a user

This API removes a user from a team 😊

DELETE https://graph.microsoft.com/beta/teams/{teamsId}/members

Check out the corresponding Microsoft Graph documentation for more information! (Delete team members or owners)

Summary

I have already had different discussions with partners and customers about the problem caused by the sync delay. This API is a big improvement in the Graph teams API. Just love it!!!

Note that this API is still in beta and seems to be still under development. During my tests, I was facing different errors like getting Bad Request when trying to delete a user from a team. However, this will be the way to go and I am very happy that Microsoft is introducing this new approach. I am really looking forward to seeing the improvements that the Microsoft Graph Teams team will be adding to those new APIs.