I would like to query the Google Workspace API in order to obtain the Storage Consumed by a user. I am using .NET 7 C# to access the Google Directory and GMAIL configuration for users. This connects to a service application and uses impersonation, and this is all working correctly. I have added DriveService.Scope.Drive scope to my Scopes Array and this Scope is enabled in my Google API Service. I am calling the following function:
public void GetUserStorageUsage(string emailAddress)
{
// Create Directory API service.
DriveService driveService = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = GetOAuthServiceAccountCredential(emailAddress),
ApplicationName = ApplicationName
});
var x = driveService.About.Get();
if(x !=null)
{
var z = x.Execute();
}
}
and it is throwing the following exception from the Google.Apis package:
Google.GoogleApiException
HResult=0x80131500
Source=Google.Apis
StackTrace:
at Google.Apis.Requests.ClientServiceRequest`1.<ParseResponse>d__38.MoveNext() in Google.Apis.Requests\ClientServiceRequest.cs:line 157
at Google.Apis.Requests.ClientServiceRequest`1.Execute() in Google.Apis.Requests\ClientServiceRequest.cs:line 103
I added a break point inside the ClientServiceRequest.cs so that I could look at the HttpResponseMessage and in calling:
https://www.googleapis.com/drive/v3/about
I am receiving a 400 Status Code with a reason phrase of "Bad Request"
Perhaps my approach is wrong? If anyone has insight I would appreciate it. I have little luck finding examples of obtaining Google Workspace User Storage Usage.
Here is the impersonation function
public ServiceAccountCredential GetOAuthServiceAccountCredential(String IpersonatedUser)
{
ServiceAccountCredential credential;
using (FileStream? stream = new FileStream(Filename , FileMode.Open, FileAccess.Read))
{
credential =
GoogleCredential
.FromStream(stream)
.CreateScoped(Scopes)
.CreateWithUser(IpersonatedUser)
.UnderlyingCredential as ServiceAccountCredential;
}
//credential.User = IpersonatedUser;
//FieldInfo userField = typeof(ServiceAccountCredential).GetField("User", BindingFlags.NonPublic | BindingFlags.Instance);
//userField.SetValue(credential, IpersonatedUser);
return credential;
}
And here are the scopes:
private String[] Scopes = {
DirectoryService.Scope.AdminDirectoryCustomer,
DirectoryService.Scope.AdminDirectoryDomain,
DirectoryService.Scope.AdminDirectoryGroup,
DirectoryService.Scope.AdminDirectoryGroupMember,
DirectoryService.Scope.AdminDirectoryOrgunit,
DirectoryService.Scope.AdminDirectoryUser,
DirectoryService.Scope.AdminDirectoryUserAlias,
GmailService.Scope.GmailSettingsBasic,
GmailService.Scope.GmailSettingsSharing,
DriveService.Scope.Drive
};
Thanks
This is my drive service account sample
using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v3;
using Google.Apis.Services;
Console.WriteLine("Google drive api service account example, workspace delegation");
const string PathToServiceAccountKeyFile = @"C:\Development\FreeLance\GoogleSamples\Credentials\workspaceserviceaccount.json";
var credential = GoogleCredential.FromFile(PathToServiceAccountKeyFile)
.CreateWithUser("[email protected]") // delegate to user on workspace.
.CreateScoped(new[] {DriveService.ScopeConstants.Drive});
// Create the Drive service.
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential
});
var result = await service.Files.List().ExecuteAsync();
foreach (var file in result.Files)
{
Console.WriteLine(file.Id);
}
about .get requires that you pass the fields var
var request = service.About.Get();
request.Fields = "*";
var aboutResponse = await request.ExecuteAsync();
var json = JsonSerializer.Serialize(aboutResponse);
Console.WriteLine(json);