Which groups allow selecting the properties allowExternalSenders or autoSubscribeNewMembers? - microsoft-graph-api

When I select the properties allowExternalSenders or autoSubscribeNewMembers for a group synced from an on-premise Active Directory, I get the following error via Graph API SDK:
403 Forbidden
Graph service exception Error code: AppOnlyAccessNotEnabledForTarget
Error message: App Only access is not allowed for target resource: 'a1d0c98e-fb7e-40c4-a7b5-ccf6d96cba57#34f0717f-f1a0-4894-b310-d379993504b9'.
The Graph Explorer displays the following 404 error, even though it is not a mailbox:
{
"error": {
"code": "MailboxNotEnabledForRESTAPI",
"message": "REST API is not yet supported for this mailbox.",
"innerError": {
"request-id": "5beae8eb-4a59-404f-bd42-0c6aa2a25abd",
"date": "2020-03-31T13:02:11"
}
}
}
An example request looks like this:
https://graph.microsoft.com/v1.0/groups/{id}?$select=id,deletedDateTime,assignedLicenses,description,displayName,groupTypes,licenseProcessingState,mail,mailEnabled,mailNickname,onPremisesLastSyncDateTime,onPremisesSecurityIdentifier,onPremisesSyncEnabled,onPremisesDomainName,onPremisesSamAccountName,preferredDataLocation,securityEnabled,securityIdentifier,visibility,resourceProvisioningOptions,allowExternalSenders,autoSubscribeNewMembers
Which property should I use to decide if I should try to select these properties or not? I want to avoid missing the properties for groups which actually do expose these properties, so I do not simply want to guess.

Slightly different take on this answer, Microsoft even thought only providing one API for groups, there are effectively two different objects returned, SecurityEnabled = True or False. If Security = True then you can not ask for the follow attributes
(allowExternalSenders,autoSubscribeNewMembers,hideFromAddressLists,hideFromOutlookClients)
Is this ok, NO its not ok, Microsoft needs to return null instead of providing THE WRONG ERROR MESSAGE and sending people like us into multi hour head scratchers.
In my code, I now check if securityEnabled is true or false and have a different set of attributes depending.

The mailbox is on a dedicated (on premise) Microsoft Exchange Server or is not a valid (configured) Office 365 mailbox. Contact your Exchange or Office admin to apply any of these recommended solutions.
To filter Office 365 groups you can do this:
https://graph.microsoft.com/v1.0/groups?$filter=groupTypes/any(c:c eq 'Unified')

Related

Slack Conversations API conversations.kick returning "channel_not_found" for a public channel

I am writing a Slack integration that can boot certain users out of public channels when certain conditions are met. I have added several OAuth scopes to the bot token, including the following:
channels:history
channels:manage
channels:read
chat:write
chat:write.public
groups:write
im:write
mpim:write
users:read
I am writing my bot in Python using the slack-bolt library and asyncio. However when I try to invoke this code:
await app.client.conversations_kick(channel=channel_id, user=user_id)
I get the following error:
slack_sdk.errors.SlackApiError: The request to the Slack API failed. (url: https://www.slack.com/api/conversations.kick)
The server responded with: {'ok': False, 'error': 'channel_not_found'}
I know for a fact that both the channel_id and user_id arguments I'm passing in are valid. The channel ID I'm using is the string C01PAE3DB0A. I know it is valid because I can use the very same value for channel_id in the following API call:
response = await app.client.conversations_info(channel=channel_id)
And when I call conversations_info like that I get all of the information about my channel. (The same is true for calling users_info with the user_id - it returns successfully.) So why is that when I pass my valid channel_id parameter to conversations_kick I consistently receive this channel_not_found error? What am I missing?
So I got in touch directly with Slack support about this and they confirmed that there is a bug on their end. Specifically, the bug is that I should have received a restricted_action error response instead of a channel_not_found response. Apparently this is a known issue that is on their backlog.
The reason the API call would (try to) return this restricted_action error is simply because there is a workspace setting that, by default, prevents non-admins from kicking people out of public channels. Furthermore, this setting can only be changed by the workspace owner - one tier above admins.
But assuming you are the owner of the Slack workspace, you simply have to log into the Settings & Permissions page, which should look something like this:
And then you have to change the setting labeled "People who can remove members from public channels" from "Workspace admins and owners only (default)" to "Everyone, except guests."
Once I made that change, my API calls started succeeding.

Create team from group fails with exception

I created teams in Microsoft Teams (from groups as documented here) via the C# graph-api sdk without any problems - everything was working just fine.
But suddenly this is not working anymore. I will always get the following exception at the line return await graphServiceClient.Teams.Request().AddAsync(team);:
Message: Failed to execute Templates backend request
CreateTeamFromGroupWithTemplateRequest. Request Url:
https://teams.microsoft.com/fabric/emea/templates/api/groups/theGroupId/team,
Request Method: PUT,
And further:
Team Visibility can not be specified as it is inherited from the
group.
I know that the visibility property must not be set if creating the team from a group as it states in the Microsoft documentation:
The team that's created will always inherit from the group's display name, visibility, specialization, and members. Therefore, when making this call with the group#odata.bind property, the inclusion of team displayName, visibility, specialization, or members#odata.bind properties will return an error.
But the currently used code below shows that I am not setting any forbidden properties - and this code worked for the last few days, too:
private async Task<Team> CreateTeamFromGroup(string groupId)
{
var graphServiceClient = [...]
var groupResourceLink = $"https://graph.microsoft.com/v1.0/groups('{groupId}')";
var team = new Team
{
AdditionalData = new Dictionary<string, object>()
{
{ "template#odata.bind", "https://graph.microsoft.com/beta/teamsTemplates('standard')" },
{ "group#odata.bind", groupResourceLink }
},
Channels = new TeamChannelsCollectionPage
{
new Channel
{
DisplayName = "WhatEver"
}
}
};
return await graphServiceClient.Teams.Request().AddAsync(team);
}
Is anyone else experiencing this problem? Was there an API change? Was the teams backend changed? Anyone any ideas?
P.S.: I am using the latest NuGet-Package for Microsoft Graph - downgrading didn't help.
Update (with a not very satisfying work-around)
The error can be reproduced via the graph api explorer, too.
The POST command above issues a PUT command, that is described here. With this request, the team can be created.
The documentation and the graph api snippet for C# is out-dated, though. You have to add odatatype = null to the properties when using the sdk
Unfortunately it is not possible to add channels in the same step. If you specify the property 'channels' it will just be ignored.
Update (Detailed error message)
System.AggregateException: 'One or more errors occurred. (Code:
BadRequest Message: Failed to execute Templates backend request
CreateTeamFromGroupWithTemplateRequest. Request Url:
https://teams.microsoft.com/fabric/emea/templates/api/groups/theGroupId/team,
Request Method: PUT, Response Status Code: BadRequest,
ErrorMessage : {"errors":[{"message":"Team Visibility can not be
specified as it is inherited from the
group."}],"operationId":"639448e414ece64caee8f52839585bf7"} Inner
error: AdditionalData: date: 2020-11-24T10:21:22 request-id:
37a28cac-3ac5-4bd2-a061-daf44c442fac client-request-id:
37a28cac-3ac5-4bd2-a061-daf44c442fac ClientRequestId:
37a28cac-3ac5-4bd2-a061-daf44c442fac )'
Just tested this morning and I can say, that the "old way" by using the beta API to create a team with a template works again. Don't know, how many other ways exist to do these things, but here is our current request, that works now (again).
POST https://graph.microsoft.com/beta/teams
{
"displayName": "My Group Name",
"description": "Some description",
"template#odata.bind": "https://graph.microsoft.com/beta/teamsTemplates('educationClass')",
"owners#odata.bind": [
"https://graph.microsoft.com/beta/users('<someValidUserId>')"
]
}
I think this will be just an intermediate state and when the bugs are fixed, they will publish the new version again and this kind of creation will fail again, but if in this case the v1.0 documented way will work this wouldn't be a big problem. But being informed BEFORE there roll-out starts would be great.
This was a Microsoft issue/ bug and is currently being fixed as stated here.

OpenExtensions: Find and retrieve Events with a given extension

I'm looking to write events to a users calendar that correspond objects in my system. I also want the ability to update and/or delete those that change between runs of the process that updates the user's calendar.
To this end I'm using Open Extensions to write additional data onto the Calendar Events that I'm creating. This is working nicely and I can see the Extension data being written.
I can use a $filter to query for events that I have written to the user's calendar:
/v1.0/me/events?$filter=Extensions/any(f: f/id eq '{id}')
This works fine and I'm seeing the results I expect. It's worth noting that the id in this query works just fine with either the fully qualified form of Microsoft.OutlookServices.OpenTypeExtension.{extensionName} or just using the short form of {extensionName}
However I cannot get the events to return with the $expanded Extension. I've tried the examples from the docs but using this query it fails:
/me/events?$filter=Extensions/any(f: f/id eq '{id}')&$expand=Extensions($filter=id eq '{id}')
Like this:
{
"error": {
"code": "BadRequest",
"message": "Parsing Select and Expand failed.",
"innerError": {
"date": "2020-06-19T17:14:59",
"request-id": "d1125156-05a6-499a-b9a4-6c66e5ce377d"
}
}
}
I need the expanded Extension data to correlate the Calendar event back to the objects in my system to allow for updates or deletes as needed.
Does anyone know what might be happening or how to resolve this?
I got an answer through another question: Receiving 400s and 500s when attempting to get singleValueExtendedProperties
The issue is that the = symbol inside the $expand expression needs to be uriEncoded. The correct query to use is: /me/events?$filter=Extensions/any(f: f/id eq '{id}')&$expand=Extensions($filter%3Did eq '{id}')

Using OR in filters for Office 365 Service Communications API or filtering by multiple IDs

How can I filter by multiple IDs using the Office 365 Service Communications API?
I'm getting the current status using https://manage.office.com/api/v1.0/{tenent}/ServiceComms/CurrentStatus which gives me incident IDs. I'm trying to use those IDs to get the messages affiliated but the message endpoint /ServiceComms/Messages is not working well with the filters.
The documentation shows:
I've tried:
/ServiceComms/Messages?ID=CR555555,/ServiceComms/Messages?ID='CR555555', /ServiceComms/Messages?Id=CR555555,/ServiceComms/Messages?Id='CR555555' - Returns everything (doesn't filter)
/ServiceComms/Messages?$filter=ID eq 'CR555555' - Returns Error
/ServiceComms/Messages?$filter=Id eq 'CR555555' - Returns 1 result
/ServiceComms/Messages?$filter=Id eq 'CR555555' or Id eq 'CR555556' - Returns error
I was able to get an AND result using
$filter=MessageType eq Microsoft.Office365ServiceComms.ExposedContracts.MessageType'Incident' and EndTime ge 2019-07-25T00:00:00Z but OR always errors with the message "Filter {filter} is invalid. Expected '<Item> <operator> <Value>' pattern."
You need to use Microsoft.Office365ServiceComms.ExposedContracts.MessageType'Incident' as your MessageType.
A request to /Messages should return you a odata context at the top of the response. For example:
{
"#odata.context": "https://office365servicecomms-prod.cloudapp.net/api/v1.0/{{TenantID}}/$metadata#Messages",
...
}
If you query that, you receive the metadata along with the possible filters. I cannot give you an example as of today (2020-02-16) a query returns a 500 Internal Server Error. Microsoft is working on a fix. Maybe it works again by the time you read my reply.
Complete example:
https://manage.office.com/api/v1.0/{{TenantID}}/ServiceComms/Messages?$filter=MessageType eq Microsoft.Office365ServiceComms.ExposedContracts.MessageType'Incident' and LastUpdatedTime ge 2020-02-13T00:00:00.000Z
And yes, the ID filter must be written 'Id'. Microsofts documentation has a lot of wrong information in it.

How to search the group by the DisplayName using Microsoft Graph?

According to the document, I can list the Office 365 Groups by using the following Graph API:
GET https://graph.microsoft.com/v1.0/groups
I have a C# Web application, and there is a input for searching by the Group DisplayName. Any idea how to query groups based on the DisplayName?
I have tried the following URL: https://graph.microsoft.com/v1.0/groups?$search="displayName:Test" in the MS Graph Explorer which didn't work.
I get the following error.
{
"error": {
"code": "Request_UnsupportedQuery",
"message": "This query is not supported.",
"innerError": {
"request-id": "35d90412-03f3-44e7-a7a4-d33cee155101",
"date": "2018-10-25T05:32:53"
}
}
Any suggestion is welcomed.
Thanks in advance.
According to your description, I assume you want to search the Group by the DisplayName using the search parameters.
Based on this document, we can currently search only message and person collections. So we couldn't use the search parameter.
We can use the filter query parameter to search the Group by DisplayName. For example, we can search the groups whose displayName is start with 'Test',the request url like this:
https://graph.microsoft.com/v1.0/groups?$filter=startswith(displayName,'Test')
Here is C# code that I wrote to get a group using the DisplayName. This code requires a reference to the OfficeDevPnP.Core.
private static async Task<Group> GetGroupByName(string accessToken, string groupName)
{
var graphClient = GraphUtility.CreateGraphClient(accessToken);
var targetGroupCollection = await graphClient.Groups.Request()
.Filter($"startsWith(displayName,'{groupName}')")
.GetAsync();
var targetGroup = targetGroupCollection.ToList().Where(g => g.DisplayName == groupName).FirstOrDefault();
if (targetGroup != null)
return targetGroup;
return null;
}
UPDATE
I see that the answer has already been accepted, but I came across the same issue and found that this answer is out of date. For the next person, this is the update:
The 'search' functionality does work. Whether it was fixed along the way or always has, I am not sure.
'groups' support search,
both the v1 and beta api support search,
search only works on 'displayName' and 'description' fields,
searching on 'directory objects' require a special header: 'ConsistencyLevel: eventual'
Point number 4 is what tripped me up!
Your request would look like this:
https://graph.microsoft.com/v1.0/groups?$search="displayName:Test"
With the request header:
ConsistencyLevel: eventual
There is another catch: You can only specify the first 21 characters and the search always uses 'startsWith'. You're out of luck if you specify more than that: The search always fails.

Resources