The MS Graph rest API surfaces a resourceProvisioningOptions attribute to indicate whether a MS365 group is also a Team (see below). However, those values do not appear to be available in the GraphServiceClient.
I found this post, and used the sites endpoint to get the associated SharePoint URL for an M365 group. But some M365 groups have SharePoint sites and are not Teams.
The only other option I found was to use the teams endpoint and catch the exception when no team is found for the group ID. But then I still have to do the additional sites endpoint query to get the SharePoint URL.
Does anyone know of another/better way to distinguish between Team/non-Team M365 groups when using the GraphServiceClient?
I'd like to pile on to the helpful post by Baker_Kong.
This functionality is available in both the beta and v1.0 endpoints. It is not described in the v1.0 metadata (which we use to generate the model) and that is why you aren't seeing this in the object model. Until this is resolved, you could use the beta client or:
// Get only groups that have teams.
var groupsThatHaveTeams = await client.Groups.Request().Filter("resourceProvisioningOptions/Any(x:x eq 'Team')").GetAsync()
// When the metadata is fixed, each group will have a ResourceProvisioningOptions property that you can inspect for the 'Team' value.
// Until then, you'd need to look at the Group.AdditionalData dictionary for the resourceProvisioningOptions key and check if it has the 'Team' value.
var groupsThatMayHaveTeams = await client.Groups.Request().Select("id,resourceProvisioningOptions").GetAsync();
cross posted from https://github.com/microsoftgraph/msgraph-sdk-serviceissues/issues/44#issuecomment-752775347
#Tracy,
I have a test the SDK in a console app, I believe this property is under the group entity:
or you can add select option to omit the returned properties:
graphClient.Groups.Request().Select("id,resourceProvisioningOptions").GetAsync().Result;
BR
Related
I'm trying to create new Sharepoint document locations in my Dynamics365 (in the cloud) system, and I'm trying to link those to an existing Sharepoint Site (collection), as well as to a custom entity of my own.
I tried to do this:
POST /api/data/v9.2/sharepointdocumentlocations
Accept:application/json
Authorization: Bearer (valid JWT token)
Content-Type:application/json
OData-Version: 4.0
OData-MaxVersion: 4.0
{
"name": "WebDocuments",
"description": "Some useful description",
"sharepointdocumentlocation_parent_sharepointsite#odata.bind" : "sharepointsites(0f66e9e3-5dfc-ec11-82e5-0022489f9669)",
"relativeurl": "site",
"customEntity_SharePointDocumentLocations#odata.bind": "my_customentity(a654d179-ab61-ec11-8f8f-000d3a64d05c)"
}
but no matter what I try, I keep getting errors - mostly along the lines of:
An error occurred while validating input parameters: Microsoft.OData.ODataException: An undeclared property 'sharepointdocumentlocation_parent_sharepointsite' which only has property annotations in the payload but no property value was found in the payload. In OData, only declared navigation properties and declared named streams can be represented as properties without values.
I have been researching and found several blog posts offering help - unfortunately, none of that has helped me solve my issue.
I tried to use various field names:
sharepointdocumentlocation_parent_sharepointsite#odata.bind
ParentLocationOrSite
and quite a few more - yet without any success.
Any ideas? How can I create a new Sharepoint document location in Dynamics365, and set its ParentLocationOrSite and RegardingObjectId properties in the POST request?
The correct syntax for that field should be:
parentsiteorlocation_sharepointsite#odata.bind
as you have another lookup pointing to a custom entity, I suggest to use my tool Dataverse REST Builder to create the Web API requests.
I used the previous beta Bookings API for getting appointments in a timeframe, the previous structure of bookingappointment just worked there.
Right now I try to update the client to use the production ready v1 API, and all appointments returned by calenderview not containing Customer data.
I'm pretty sure those appointments should have customers, there are sent invitation emails to customers regarding the appointment.
The /customers endpoint shows all customers.
The issue reproducable by C# SDK and Graph Explorer as well.
GraphExplorer
There is a workaround, or what am I missing here?
Looks like a bug in Graph API.
According to the documentation the customers property is optional. Sometimes you have to specify optional property in $select statement.
You can try to add Select() to calendar view request and check whether it will work.
var queryOptions = new List<QueryOption>()
{
new QueryOption("start", "2022-01-30T00:00:00Z"),
new QueryOption("end", "2022-01-31T00:00:00Z")
};
var calendarView = await graphClient.Solutions.BookingBusinesses["{id}"].CalendarView
.Request(queryOptions)
.Select("customers") // select customers
.GetAsync();
This a known Graph API bug, until it is resolved,
I using listview to find all appointments, and getting appointments one by one using the /appointments/AAMkADQ0YTdhYWQAAA= endpoint using the Ids from listview.
Example:
GET https://graph.microsoft.com/v1.0/solutions/bookingBusinesses/Contosolunchdelivery#contoso.onmicrosoft.com/appointments/AAMkADKnAAA=
This way the customer field always shows up, if there are regarding customers for a given appointment.
Source
Relevant package versions:
Microsoft.EntityFrameworkCore: 3.1.9
Microsoft.Graph: 3.28
I'll illustrate the inconsistencies with a few examples:
Retrieving the groups by using the powershell script
The script for getting the groups is provided here: Display users and groups assigned to an Application Proxy application
.
Unique groups returned: 157
Remarks: The count of groups along with object ids corresponds to the ones I can see listed on Azure Active Directory blade on the Azure Portal so I'm using this as reference for the other approaches.
Getting groups via .NET core using the App Id
await graphServiceClient.ServicePrincipals.Request().Filter($"appId eq '{appId}'").Expand("AppRoleAssignedTo");
Unique groups returned: 101
Remarks: I am unable to identify why certain groups aren't returned. To confirm that a permissions issue is not responsible for the discrepancy, I tried to manually retrieve the groups using the objectIds of the missing groups as below:
var group = await graphServiceClient.Groups[id].Request().Expand("AppRoleAssignments").GetAsync();
do
{
assignments.AddRange(group.AppRoleAssignments.CurrentPage.ToList().Where(x => x.ResourceId.ToString().Equals(appServicePrincipalId)).ToList());
} while (group.AppRoleAssignments.NextPageRequest != null);
I was able to succesfully retrieve the missing groups using this approach.
Getting groups via .NET core using the Service Principal
In order to be through, I exchanged the appId approach with one that relies on the service principal as below but the results were the same as with the AppId.
await graphServiceClient.ServicePrincipals[appServicePrincipalId].AppRoleAssignedTo.Request().GetAsync()
Unique groups returned: 101
Retrieving the groups by adapting the powershell script to .NET
var tx = await graphServiceClient.Groups.Request().Expand("AppRoleAssignments").GetAsync()
do
{
foreach (var group in tx)
{
do
{
assignments.AddRange(group.AppRoleAssignments.CurrentPage.ToList().Where(x => x.ResourceId.ToString().Equals(appServicePrincipalId)).ToList());
if (group.AppRoleAssignments.NextPageRequest != null)
{
group.AppRoleAssignments = await group.AppRoleAssignments.NextPageRequest.GetAsync();
}
} while (group.AppRoleAssignments.NextPageRequest != null);
}
tx = await tx.NextPageRequest.GetAsync();
} while (tx.NextPageRequest != null);
Here the approach is to iterate over all groups and then filter those with the correct service principal id.
Unique groups returned: 136
Unusually enough, while I'm able to retrieve more groups using this approach, it actually fails to retrieve certain groups that are obtained via the App Id/Service principal approach. Aggregating both of them, leads to a commulative total of 146
Due to confidentiality reasons, I unfortunately cannot reveal the specifics of the groups or their respective contents but each of the missing groups have members in them and are assigned atleast one AppRole.
It turns out that the approaches were correct, the library version was just outdated. Using Microsoft.Graph: 4.15, I can fetch the required groups using any of the aforementioned methods.
Recently when working with Lex in C#, I have referenced AWSCore.dll and AWSLex.dll and still trying to get a method that exposes all available Lexchatbots that I created in the Aamazon server.
var amazonPostRequest = new Amazon.Lex.Model.PostContentRequest();
var amazonPostResponse = new Amazon.Lex.Model.PostContentResponse();
used both methods to get all other information. Methods in request for bot name and alias is for setting and there is no method in response for getting available Lexchatbots in the server.
I don't believe that the Lex SDK supports this call directly.
Use the AWS Lex REST API to get a list of bots:
GET https://<your aws region endpoint>/bots/
https://docs.aws.amazon.com/lex/latest/dg/API_GetBots.html
After a long research I found the answer to my problem, It may help others.
First we need to add the AWSSDK.LexModelBuildingService through Nuget. This will add reference to the DLL.
From that all methods already exposed. We need to create both GetBotsRequest and GetBotsResponse methods.
var botRequest = new Amazon.LexModelBuildingService.Model.GetBotsRequest();
var botResponse = new Amazon.LexModelBuildingService.Model.GetBotsResponse();
Then we need to call lex model building service client
var amazonmodel = new AmazonLexModelBuildingServiceClient("YourAccesKeyId","YourSecretAccessKey",Amazon.RegionEndpoint.USEast1);
After that we can get the response of inbuilt method of GetBots()
botResponse = amazonmodel.GetBots(botRequest);
We will get the list of bots metadata
List<Amazon.LexModelBuildingService.Model.BotMetadata> bots = botResponse.Bots;
Every details about each bot created will be available in the array of list of bots
There is almost all methods in getting details from Lex configuration in LexModelBuildingService dll
Note:
In IAM (Identity Access Management) in AWS we need to give Access to have Lex components in Policy section. AWSLexFullAccess
or
atleast arn:aws:lex:region:account-id:bot:* access in policy
I want to know how can I use GMB API to fetch reviews. According to google documentation we have to make a GET request to https://mybusiness.googleapis.com/v3/{name=accounts/*/locations/*}/reviews
But what is meant by {name=accounts/*/locations/*} and from where we can get the value of accounts & locations.
Also this requires OAuth 2.0. If I get a access_token then GET request will be like this:-
https://mybusiness.googleapis.com/v3/{name=accounts/*/locations/*}/reviews?access_token=token
This is very confusing. Can somebody tell me how to use GMB API correctly to fetch google reviews.
Using Google OAuth 2 Playground
For testing acquisition of Google reviews
Create a project
Console.cloud.google.com
Sign in as {projectowner}#google.com
Select a project from the dropdown in the header or click new project
Go to APIs & Services in the left menu
Enable the Google My Business API; this requires validation by Google and may take a couple of days. They will email you.
Go to developers.google.com/oauthplayground
Using the settings gear, set OAuth flow to Client-side and click Use your own OAuth credentials
Get the client id from console.developers.google.com/apis and paste it in
Put this into scope: https://www.googleapis.com/auth/plus.business.manage and authorize it with {projectowner}#gmail.com
Exchange auth code for token
To get the account name:
Set Request URI to https://mybusiness.googleapis.com/v4/accounts and send a Get request
Copy the entire string value at “name”: not including quotes; it may be 20+ numeric digits
To get location names:
Set Request URI to https://mybusiness.googleapis.com/v4/accounts/{paste account name here}/locations where {paste ... here} is the account name you copied
The returned JSON contains all of your locations
Copy the location names including quotes and commas to a temporary holding document; they will be used in a JSON array in the next step
To get multiple locations’ reviews
a. Set Request URI to https://mybusiness.googleapis.com/v4/accounts/{account name here}/locations:batchGetReviews and the Method to Post
b. Set Request Body to
{
"locationNames": [
"accounts/999999999999999999999/locations/88888888888888888888",
"accounts/999999999999999999999/locations/77777777777777777777",
.
.
.
"accounts/999999999999999999999/locations/11111111111111111111"
],
"pageSize": 200,
"orderBy": "updateTime desc",
"ignoreRatingOnlyReviews": false
}
using the account names you saved from the location JSON for each line of the array
If you have more than 200 total reviews you will have to add "pageToken": string into the JSON body where string is a value returned in the preceding POST.
But what is meant by {name=accounts//locations/} and from where we can get the value of accounts & locations.
To get this details first get the account using the following API (https://mybusiness.googleapis.com/v4/accounts?access_token=#####)
Once you have the account list, fetch Account Location list using the following API (https://mybusiness.googleapis.com/v3/" + name + "/locations) in the response of this API you will get the {name=accounts/*/locations/*}.
Also this requires OAuth 2.0. If I get a access_token then GET request will be like this: https://mybusiness.googleapis.com/v3/{name=accounts/*/locations/*}/reviews?access_token=token
Yes, that is correct.
Let me know if this work's for you.