RATE_LIMIT_EXCEEDED exception on getting Account List(Google My Business API) - google-my-business-api

Nowadays we are implementing My Business api integration for our platform.
I followed this document "https://developers.google.com/my-business/content/prereqs" and after I trying to get account list an error occurred;
<HttpError 429 when requesting https://mybusinessaccountmanagement.googleapis.com/v1/accounts?alt=json returned "Quota exceeded for quota metric 'Requests' and limit 'Requests per minute' of service 'mybusinessaccountmanagement.googleapis.com' for consumer 'project_number:XXXX'.". Details: "[{'#type': 'type.googleapis.com/google.rpc.ErrorInfo', 'reason': 'RATE_LIMIT_EXCEEDED', 'domain': 'googleapis.com', 'metadata': {'quota_metric': 'mybusinessaccountmanagement.googleapis.com/default_requests', 'consumer': 'projects/XXXX', 'quota_limit': 'DefaultRequestsPerMinutePerProject', 'service': 'mybusinessaccountmanagement.googleapis.com'}}]">
output = self.service.accounts().list().execute();
Anyone faced this type issue ?
Regards.

You can use a rateLimiter:
import com.google.api.client.json.GenericJson;
import com.google.common.util.concurrent.RateLimiter;
...
//requests per second
private static final RateLimiter rateLimiter = RateLimiter.create(5.0);
...
private static GenericJson executeWithRateLimiter(request,
RateLimiter rateLimiter) {
rateLimiter.acquire();
return request.execute();
}

Related

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.

Microsoft Teams Graph API - Invalid bind property name owners in request

I'm currently having major issues with creating teams from the Graph API. I was initially trying to create teams based on groups, however I have found out today that you can now create a team without creating a group first then waiting 15 minutes to then create the team from the following link. This would make things considerably simpler.
https://learn.microsoft.com/en-us/graph/api/team-post?view=graph-rest-1.0
I am using the Microsoft.Graph SDK (v3.12.0 released 26th Aug) so replicated the http call using the SDK as follows.
var team = new Team
{
DisplayName = "My Group Name",
Description = "My Group Description",
AdditionalData = new Dictionary<string, object>()
{
{"template#odata.bind", "https://graph.microsoft.com/v1.0/teamsTemplates('educationClass')"},
{"owners#odata.bind", $"[\"https://graph.microsoft.com/v1.0/users('{usersGuid}')\"]"}
},
};
var response = await _graphClient.Teams
.Request()
.AddAsync(team);
The code above gives a:
[16:14:01 ERR] An unhandled exception has occurred while executing the request.
Status Code: BadRequest
Microsoft.Graph.ServiceException: Code: BadRequest
Message: Invalid bind property name owners in request.
If I remove the line
{"owners#odata.bind", $"[\"https://graph.microsoft.com/v1.0/users('{usersGuid}')\"]"}
from the code I get the following:
ErrorMessage : {"errors":[{"message":"A team owner must be provided when creating a team in application context."}]
Any advice would be greatly appreciated.
Thanks,
Nick
In v1.0 the owners relationship is not currently present, so you have to use the beta endpoint.
POST: https://graph.microsoft.com/beta/teams
with the following body format
{ "template#odata.bind":"https://graph.microsoft.com/beta/teamsTemplates('standard')", "displayName":"Test Team", "description":"Test description", "owners#odata.bind":["https://graph.microsoft.com/v1.0/users/{user guid}"] }
Note: the user guid should also be bare, i.e without the brackets and quotes in your example.

Error when querying Microsoft Graph API Shifts: "MS-APP-ACTS-AS header needs to be set for application context requests"

We are trying to query shifts in the Microsoft Graph API using a C# app, now that StaffHub got deprecated , in the past we were getting an Unknown Error which looked like a permissions issue.
In the docs I noticed permissions for Schedule.ReadAll and Schedule.ReadWriteAll so I added them to the application permissions in our App Registration in Azure.
Now when we send the request to https://graph.microsoft.com/beta/teams/{teamid}/schedule we get this error:
Microsoft.Graph.ServiceException: 'Code: Forbidden Message: {"error":{"code":"Forbidden","message":"MS-APP-ACTS-AS header needs to be set for application context requests.","details":[],"innererror":{"code":"MissingUserIdHeaderInAppContext"}}}
The documentation says the Schedule permissions are in private preview, are these required for querying a schedule & shifts, and if so, is it possible to request access to the private preview?
I'm in the same situation. It's possible to request private preview access (we have), but I'm guessing that it's primarily granted to Microsoft partners or at least have a connection at Microsoft.
The workaround for me has been getting access on behalf of a user. It does however require the user to enter username and password in order to get an access token, so it might not be a perfect solution for you. But it works. You need to add (and, I believe, grant admin consent for) delegated permissions for this to work, either Group.Read.All or Group.ReadWrite.All.
Edit:
I've got it working now. We have private preview access, so I'm not sure this will help you unless you do too, but as I understand it will be available eventually. Given your question, I presume you already have an access token.
Add MS-APP-ACT-AS as a header with the user ID of the user you want the Graph client to act as.
If you're using the Graph SDK for .NET Core you can just add a header to the authentication provider:
public IAuthenticationProvider GetAuthenticationProviderForActingAsUser(string userId, string accessToken)
{
return new DelegateAuthenticationProvider(
requestMessage =>
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
// Get event times in the current time zone.
requestMessage.Headers.Add("Prefer", "outlook.timezone=\"" + TimeZoneInfo.Local.Id + "\"");
requestMessage.Headers.Add("MS-APP-ACTS-AS", userId);
return Task.CompletedTask;
});
}
Then you call the graph service client:
var authenticationProvider = GetAuthenticationProviderForActingAsUser(userId, accessToken);
var graphClient = new GraphServiceClient(authenticationProvider);
You should then be able to fetch the shifts:
var shifts = await graphClient.Teams[teamId].Schedule.Shifts
.Request()
.AddAsync(shift);

Failed to authenticate to Cloud IAP Backend from Cloud Tasks HTTP Request

I'm trying to use Cloud Tasks HTTP Requests to reach a Kubernetes endpoint behind an HTTPS Load Balancer protected by Cloud IAP.
The endpoint works using any Gsuite company account as it should be but when the Cloud Task executes this is the Cloud Audit - Data Access log (only important parts displayed)
authenticationInfo: {
}
authorizationInfo: [
0: {
permission: "iap.webServiceVersions.accessViaIAP"
resource: "projects/<PROJECT_NUMBER>/iap_web/compute/services/<SERVICE_NUMBER>/versions/bs_0"
resourceAttributes: {
service: "iap.googleapis.com"
type: "iap.googleapis.com/WebServiceVersion"
}
}
]
status: {
code: 7
message: "PERMISSION_DENIED"
}
I'm using the compute-engine service account to create the task so I've granted this account the appropriate permissions:
When I create the task I add the appropriate OIDC service account email to the http request
'oidc_token': {'service_account_email': <PROJECT_NUMBER>-compute#developer.gserviceaccount.com}}
I also checked the Cloud Tasks HTTP Request on another endpoint and the Authentication Bearer token is present.
I really don't have any idea at this point on how to make it work.
Thanks for the help
I found the problem, the OIDC needed a specific audience to work with Cloud IAP.
The audience needed is the IAP ClientID that could be found in API & Services > Credentials under the section OAuth 2.0 client IDs with a name starting with IAP.
Just as an example here is the python code to add a task that can be granted access by the Cloud IAP.
# This is the important part, the audience filed is very important!
oidc_token = {'service_account_email': <PROJECT_NUMBER>-compute#developer.gserviceaccount.com, 'audience': <PROJECT_NUMBER>-<NUMBER_GENERATED_AUTOMATICALLY_BY_IAP>.apps.googleusercontent.com}
http_request = {'http_method': 'POST', 'url': url, 'body': json.dumps(payload).encode(), 'headers': headers, 'oidc_token': oidc_token}
task['schedule_time'] = timestamp
created_task = client.create_task(parent, {'http_request': http_request})

YouTube Data API v3/search InvalidChannelId with no channelId specified

I'm making the following authenticated request:
GET
https://www.googleapis.com/youtube/v3/search?forMine=true&type=video&part=snippet&maxResults=50&api_key=<api_key>&order=date
I'm getting the following 400 response:
{
'error': {
'message': 'Invalid channel.',
'errors': [
{
'domain': 'youtube.search',
'message': 'Invalid channel.',
'location': 'channelId',
'locationType': 'parameter',
'reason': 'invalidChannelId'
}
],
'code': 400
}
}
As you can see, I don't specify a channelId in the request. This works for most of the accounts that I have authenticated with, but it is failing for 1 specific account and I'm not sure what I'm supposed to do with it.
Note that with the same authentication token and API key I am able to get the list of channels (https://www.googleapis.com/youtube/v3/channels) without error.
I'm guessing that the error at the least could be misleading? Or maybe there is a bug? Or maybe some sort of configuration issue?
In my case I have an account that is a member of an organization. You need to choose the organization, not the account itself (which didn't have a youtube channel created - hence the error).
Try going through the oauth flow in an anonymous window, it is not obvious what I mean if you are already logged in.

Resources