.Net - Google Play Download Sales Reports - google-api

I have a .Net Core application attempting to download the latest sales reports from my Google Play account to view and track sales statistics. These reports are stored on a Google Cloud Storage bucket "owned"/managed by the Google Play Store.
I've been unable to find many other examples or related issues in .Net and have been experiencing a storage permission issue.
I'm following the rather limited guide here: https://support.google.com/googleplay/android-developer/answer/6135870#export under "Download reports using a client library and service account"
Step 1: Create a service account
I've created a new service account for a new project as shown below. I've also granted that service account permissions for all storage objects as shown.
Step 2: Add the service account on your play console
I've also invited this new service account user to my play console and granted it permissions to the app to view it's information and financial reports.
Step 3: Fetch reports using an API call
I've created and downloaded a .JSON key for the service user.
// Scope as specified in https://support.google.com/googleplay/android-developer/answer/6135870#export
string[] scopes = new string[] { "https://www.googleapis.com/auth/devstorage.read_only" };
// Import JSON credential
var credential = GoogleCredential.FromFile(Path.Combine(Environment.CurrentDirectory, "keys/googleplay.json")).CreateScoped(scopes);
// Bucket ID of Google Play Store - Found from reports page "Copy URL"
string bucketId = "pubsite_prod_5XXXXXXXXX2";
var storage = StorageClient.Create(credential);
var bucketObjects = storage.ListObjects(bucketId);
foreach (var bucketObject in bucketObjects)
{
Console.WriteLine(bucketObject.Name);
}
This results in a permission error:
Google.Apis.Requests.RequestError\r\nsupportapp-googleplay#ascendant-nova-300105.iam.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. [403]\r\nErrors [\r\n\tMessage[supportapp-googleplay#ascendant-nova-300105.iam.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket.
The service account I've created has the storage.objects.list permission and has been invited to my Play Console as well (as shown in the screenshots). This is a storage bucket hosted/owned by Google Play and not me. How can this permissions issue be resolved to allow my linked account to access Google Play's sales reports via API?

I came back in the morning and magically things now work.
I have also changed to using fromStream instead of fromFile when creating the Google credential.
Changed:
string[] scopes = new string[] { "https://www.googleapis.com/auth/devstorage.read_only" };
var credential = GoogleCredential.FromFile(Path.Combine(Environment.CurrentDirectory, "keys/googleplay.json")).CreateScoped(scopes);
To:
GoogleCredential credential;
using (var stream = new FileStream(Path.Combine(Environment.CurrentDirectory, "keys/googleplay.json"), FileMode.Open, FileAccess.Read))
{
credential = GoogleCredential.FromStream(stream).CreateScoped(scopes);
}
However, both of these credential creation systems work just fine... Perhaps it took Google 12 hours to sync the permissions? Hopefully this example can help someone else out in the future.

Related

Get Google Sheet Data using V4 API without OAuth

Using this nodeJS example, I could get the data from a public sheet.
But how do I get the data from a non-public sheet owned by me (my google a/c) ?
Is there some way to send in the username and password as arguments ?
I don't want OAuth way as I want the data to be pulled from the sheet & displayed on a public webpage.
The other option I can think of is to have OAuth2 done once write a script to handle refresh tokens automatically as a cron every hour ?
Since this is a file that you the developer own i would recommend using a service account
If you share the file with the service account it will then have permissions to access it without you needing to go though the oauth2 steps of authorizing your application.
On google cloud console simply create Service account credentials
const {google} = require('googleapis');
const auth = new google.auth.GoogleAuth({
keyFile: '/path/to/your-secret-key.json',
scopes: ['https://www.googleapis.com/auth/spreadsheets'],
});
Then change your auth code slightly. Open the service account key file and look for the service account email address its the only one witha # in it. Share the file with the service account like you would any other user in google drive web app.
Once it has access you shouldn't need to authorize the app again.
I have a video on Google drive API upload file with Nodejs + service account which might help you a bit you just need the authorization code. Everything else you have should work as is.

Use a service account to get the list of users from Google domain

Hello all.
I have been assigned the task of fetching unanswered emails from the inbox of each member of our Google domain using Spring Boot, but I haven't been able to do it.
In first place, I need the list of users from the domain. This can be achieved via Directory API (which cannot be enabled by that name in the Google Developer console, by the way. Looks like it belongs to Admin SDK or so).
What I have faced so far is this:
There are many related questions on SO, but most of them are outdated.
Java Quickstart for Google Directory API does not include an example using service accounts, and I want to use them because my app runs in a docker container, and using Oauth means I need to manually authorize it every time I deploy a new version or restart the container.
Google documentation makes reference to "API Reference" settings in Admin console, but I don't see that section there.
I am not storing credentials in a JSON file, I have them in an environment variable instead. I am doing this:
var inputStream = IOUtils.toInputStream(apiCredentials, Charset.defaultCharset()); //apiCredentials is a string with the JSON contents.
var credential = GoogleCredential
.fromStream(inputStream, httpTransport, JacksonFactory.getDefaultInstance())
.createScoped(Collections.singleton(DirectoryScopes.ADMIN_DIRECTORY_USER));
var directoryService = new Directory.Builder(httpTransport, JacksonFactory.getDefaultInstance(), credential)
.setApplicationName("My App")
.build();
var result = directoryService.users().list()
.setPageToken(pageToken)
.setDomain("my.domain")
.setMaxResults(10)
.execute();
After this, I get a 400 Bad request error, with no further description.
What am I doing wrong here?

Classroom API - Access classroom with Service Account

I need some help as I'm really stuck!!!! I have spent days and hours on this one but I can't figure it. I have searched all possible forums and other similar posts without any success.
So, the requirement :
We are trying to integrate Classroom API on our .Net platforms. The tricky part is that they want to use service accounts.
The problem :
Google.Apis.Requests.RequestError The caller does not have permission [403]
The caller does not have permission] Location[ - ] Reason[forbidden] Domain[global]
I have followed the documentation as shown in :
https://developers.google.com/identity/protocols/OAuth2ServiceAccount.
I understand that we need to set up a service account in the Google API Console, so I've done the following:
1) I have created a service account and enabled G Suite Domain-wide Delegation in the Google API Console
2) In the Admin Console, in Manage API Client Access, I have entered the service account's client id and have enabled scopes.
3) A have downloaded the json file with all the service account credentials (private key, email)
and the code...
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(cr.client_email)
{
Scopes = new[] { ClassroomService.Scope.ClassroomCourses },
}.FromPrivateKey(cr.private_key));
// Create the service.
service = new ClassroomService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Demo-School",
});
and the actual call to the Classroom API to create a course :
var resource = service.Courses.Create(course);
var result = await resource.ExecuteAsync();
So, despite all that, whenever i try to create a course, I get the above error.
When I try to create a Course using the Reference page (https://developers.google.com/classroom/reference/rest/v1/courses/create) it works fine. I can create courses, teachers, set permissions etc..
But when I try to do that programmatically.. i.e from a console app, there is NO way I can get it working.
Can ANYONE please advice???????What am I missing??

Need to access sharepoint online addin rest api without azure ad registration

I have a share-point addin need to create the xamarin application. So need access to all the share-point online rest API.
As per the Microsoft document we need to register app on Azure AD.
I don't want to register the app in Azure AD, I already have share point adding
I have Tried the MSAL and ADAL Library provide by Microsoft for accessing. To used them we need to register app on Azure AD.
here is the code which I have written to access direct share-point rest API.
private const string GetCalendarEventsUrl = "{tenant}/_api/web/lists/getbytitle('Project')/items?$top=4900";
public List<CalendarEvent> GetCalendarEvents()
{
var username = "{tenant}.onmicrosoft.com";
var password = "{password}";
var domain = "{domain}";
var handler = new HttpClientHandler();
handler.Credentials = new System.Net.NetworkCredential(username, password, domain);
using (var client = new HttpClient(handler))
{
using (var request = new HttpRequestMessage(HttpMethod.Get, new Uri(GetCalendarEventsUrl)))
{
request.Headers.Add("Accept", "application/json;odata.metadata=minimal");
using (var response = client.SendAsync(request).Result){
if (response.IsSuccessStatusCode) {
Console.WriteLine("response");
}
}
}
}
throw new Exception("Could not get calendar events");
}
Can I access the share-point online rest API directly?
You can't directly access the Sharepoint rest api from mobile.
Here are my findings:-
A - You need to create your own web-services which will authenticate with the Sharepoint online web apis and deploy it then you will have to connect to the newly created web-services with your mobile app to fetch and update the data.
you can find the proper description from this link
https://www.codemag.com/Article/1411031/Mobile-Apps-for-SharePoint-and-Office-365-Part-1
B - Another way is that you can add a new app, create a new app and register into the Azure AD with your own custom logics for the interactions with Sharepoint online rest api
you can find the proper description from this link
https://learn.microsoft.com/en-gb/azure/active-directory/develop/app-types
Let me know,if it helps

Using Facebook Ads API and Spring Social Facebook

I'm developing a SpringBoot application which needs to manage multiple Facebook Ad accounts. I've successfully used the Facebook Java Ads SDK:
https://github.com/facebook/facebook-java-ads-sdk
to connect to a single Facebook ads account, via a Facebook app within the same account (account A) and create a campaign and query campaigns, ads sets, etc:
public static final APIContext context = new APIContext(ACCESS_TOKEN, APP_SECRET);
public static void main(String[] args)
{
try
{
AdAccount account = new AdAccount(ACCOUNT_ID, context);
Campaign campaign = account.createCampaign().setName("Java SDK Test Campaign")
.setObjective(Campaign.EnumObjective.VALUE_LINK_CLICKS).setSpendCap(10000L)
.setStatus(Campaign.EnumStatus.VALUE_PAUSED).execute();
System.out.println(campaign.fetch());
} catch (APIException e)
{
e.printStackTrace();
}
}
Thew ACCESS_TOKEN, APP_SECRET and ACCOUNT_ID are all from the same Facebook account (account A), the one in which the Facebook app was created. The Facebook app has the ads_management permissions reviewed and approved.
Now I need to be able to access Facebook Ad Accounts from other Facebook accounts. I've used the spring-social-facebook Accessing Facebook Data tutorial:
https://spring.io/guides/gs/accessing-facebook/
To register a different Facebook account (account B) with the Facebook App, using the scopes "ads_read, ads_management" and the account ID for the new Facebook account (account B) was added to the Facebook App from the original account (account A).
However, when I used the second account's account ID in the code above I get:
{"error":{"message":"Unsupported get request. Object with ID 'act_105428933326149' does not exist, cannot be loaded due to missing permissions, or does not support this operation. Please read the Graph API documentation at https:\/\/developers.facebook.com\/docs\/graph-api","type":"GraphMethodException","code":100,"fbtrace_id":"Ee5exTqJdCp"}
Which suggests I have a permissions issue somewhere, but I'm stumped. I'm not even sure I'm following the correct approach.
I've tried googling for an example of how to use the Facebook Ads API with spring-social-facebook, but other than a few commits to the repository which don't help a great deal, I can't find one.
Facebook Ads API has tiered access. A newly registered app is in Development Tier and can only access the user's own ad accounts. You need to meet certain criteria to get promoted to Basic Tier and manage other people's ad account.

Resources