I'm trying to get some data from our google analytics instance and I'd like to use the Analytics Reporting API V4 Client Library for .NET (https://developers.google.com/api-client-library/dotnet/apis/analyticsreporting/v4) so that I can bake some of this data into an administration site we have built. I'm having trouble finding any examples of using this code and the documentation seems to be incredibly sparse. I would like to use a service account to authorize as we only need to view data associated with the analytics account which we control.
If anyone could provide some sample code or point me in the right direction to get some basic report data using the .net api, it would be greatly appreciated
Calling the Google Analytics Reporting API from C# is not particularly difficult, however all of the necessary steps do not seem to be outlined very clearly in the Google Analytics API documentation. I will try to list them all out here. While YMMV, I believe these steps to be correct as of 7/20/2016.
You can start by creating a new C# project. We'll make a console application to test called GoogleAnalyticsApiConsole. Once the project is created, we'll add a reference to the Google Analytics Reporting API V4 Client Library for .NET using the NuGet Package Manager Console (found under the Tools menu in Visual Studio 2015). Fire up the Console and issue the following command at the PM> prompt:
PM> Install-Package Google.Apis.AnalyticsReporting.v4
Installing that package will download the client libraries needed to call the Google Analytics Reporting web services along with a number of other dependencies.
In order to call the web services, you'll need to set up OAuth 2.0 access for your application. The documentation for this setup can be found here, but I will summarize below:
Login to the Google Cloud Platform Console: https://console.cloud.google.com/. Be sure to login with an account that has access to the Google Analytics accounts you are trying to query with the reporting API.
Click the Google Cloud Platform menu and select API Manager.
On the left hand side, click Credentials and then create a new project called Google Analytics API Console. Give it some time to create the new project.
After the project is created, click Credentials again if it is not already selected, and then click the OAuth Consent Screen link in the right panel. Set the Product name shown to users to Google Analytics API Console and then click Save.
Click Credentials again, and then click Create Credentials, and choose OAuth Client ID. Select Other for Application type and then enter Google Analytics API Console as the Name and click Create.
After the credential is created, you will be presented with a client ID and a client secret. You can close the dialog window.
Now, under Credentials you should see an entry under OAuth 2.0 client ids. Click the download icon to the far right of that entry to download the client_secret.json file (this file will have a much longer name). Add that file to your project at the root level once it has been downloaded and rename it to client_secret.json.
Now that the OAuth 2.0 credential has been created, we need to enable it to call the Reporting API. Select Overview and make sure Google APIs is selected in the right panel. Type in Reporting in the search box and select Analytics Reporting API V4 from the list. On the next screen, click Enable. Once this API has been enabled, you should be able to see it under the Enabled APIs list in the right panel.
Now that we've created our project and created our OAuth 2.0 credential, it is time to call the Reporting API V4. The code listed below will use the Google API and the client_secret.json file to create a Google.Apis.Auth.OAuth2.UserCredential to query the Reporting API for all sessions between the given date range for a View. The code is adapted from the Java example here.
Before executing the code, be sure to set the Build Action on the client_secret.json file to Content and the Copy to Output Directory setting to Copy if newer. There are also two variables that need to be properly set. First, in the GetCredential() method, set the loginEmailAddress value to the email address used to create the OAuth 2.0 credential. Then, in the Main method, be sure to set the ViewId in the reportRequest variable to the view that you want to query using the Reporting API. To find the ViewId, log in to Google Analytics and select the Admin tab. From there, select the view you want to query in the View dropdown on the far right and select View Settings. The View ID will be displayed under Basic Settings.
The first time the code is executed, it will bring up a web page asking if you want to allow the Google Analytics API Console to have access to the API data. Select Allow to proceed. From then on that permission will be stored in the GoogleAnalyticsApiConsole FileDataStore. If that file is deleted, then permission will need to be granted again. That file can be found in the %APPDATA%\GoogleAnalyicsApiConsole directory.
Please note that I believe this scenario will meet the needs of the OP. If this application were to be distributed to clients, then a different OAuth 2.0 scheme would most likely be necessary.
Here is the code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Google.Apis.AnalyticsReporting.v4;
using Google.Apis.AnalyticsReporting.v4.Data;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Util.Store;
namespace GoogleAnalyticsApiConsole
{
class Program
{
static void Main(string[] args)
{
try
{
var credential = GetCredential().Result;
using(var svc = new AnalyticsReportingService(
new BaseClientService.Initializer
{
HttpClientInitializer = credential,
ApplicationName = "Google Analytics API Console"
}))
{
var dateRange = new DateRange
{
StartDate = "2016-05-01",
EndDate = "2016-05-31"
};
var sessions = new Metric
{
Expression = "ga:sessions",
Alias = "Sessions"
};
var date = new Dimension { Name = "ga:date" };
var reportRequest = new ReportRequest
{
DateRanges = new List<DateRange> { dateRange },
Dimensions = new List<Dimension> { date },
Metrics = new List<Metric> { sessions },
ViewId = "<<your view id>>"
};
var getReportsRequest = new GetReportsRequest {
ReportRequests = new List<ReportRequest> { reportRequest } };
var batchRequest = svc.Reports.BatchGet(getReportsRequest);
var response = batchRequest.Execute();
foreach (var x in response.Reports.First().Data.Rows)
{
Console.WriteLine(string.Join(", ", x.Dimensions) +
" " + string.Join(", ", x.Metrics.First().Values));
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
static async Task<UserCredential> GetCredential()
{
using (var stream = new FileStream("client_secret.json",
FileMode.Open, FileAccess.Read))
{
const string loginEmailAddress = "<<your account email address>>";
return await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
new[] { AnalyticsReportingService.Scope.Analytics },
loginEmailAddress, CancellationToken.None,
new FileDataStore("GoogleAnalyticsApiConsole"));
}
}
}
}
Here are the steps updated for Sep 2019.
First, understand that there are two choices under OAuth: User credentials and Service Account credentials. User credentials are meant to be used when you do not know which Google Analytics account you will be connected to, hence the user grants your application permission. Service Account credentials are meant to be used, e.g. if you build your own dashboard for your company to display Google Analytics data.
Most of the time, if you need programmatic access to Analytics data, it is the second case.
The steps below should get you started for a simple C# example. Note that the Google web console part may vary slightly, but should be easy to find nevertheless.
Go to the Google API Console. Create a Project if prompted.
Go to Service accounts.
Create a new Service Account. You should have an account with a random-generated email address (mine is ending with xxx#xxx.iam.gserviceaccount.com)
Find the Create Key button. Choose JSON and download the file. This is your private key and your only copy. Do not lose it.
Go to your Google Analytics admin panel. Grant access to the Service Account using its email address, the same way you would grant access to other users.
The Google configuration is done. Now jump into Visual Studio.
Create a new C# Console Project.
Get the Nuget package Google.Apis.AnalyticsReporting.v4. It should also automatically download the core packages as well.
Grab the JSON file downloaded earlier, put it in the project, set its Property to Content and Copy Always.
using Google.Apis.AnalyticsReporting.v4.Data;
using System;
namespace ConsoleApplication {
class Program {
static void Main(string[] args) {
var credential = Google.Apis.Auth.OAuth2.GoogleCredential.FromFile("serviceAccount.json")
.CreateScoped(new[] { Google.Apis.AnalyticsReporting.v4.AnalyticsReportingService.Scope.AnalyticsReadonly });
using (var analytics = new Google.Apis.AnalyticsReporting.v4.AnalyticsReportingService(new Google.Apis.Services.BaseClientService.Initializer {
HttpClientInitializer = credential
})) {
var request = analytics.Reports.BatchGet(new GetReportsRequest {
ReportRequests = new[] {
new ReportRequest{
DateRanges = new[] { new DateRange{ StartDate = "2019-01-01", EndDate = "2019-01-31" }},
Dimensions = new[] { new Dimension{ Name = "ga:date" }},
Metrics = new[] { new Metric{ Expression = "ga:sessions", Alias = "Sessions"}},
ViewId = "99999999"
}
}
});
var response = request.Execute();
foreach (var row in response.Reports[0].Data.Rows) {
Console.Write(string.Join(",", row.Dimensions) + ": ");
foreach (var metric in row.Metrics) Console.WriteLine(string.Join(",", metric.Values));
}
}
Console.WriteLine("Done");
Console.ReadKey(true);
}
}
}
I had the same experience: Google's documentation is pretty in-depth but is pretty terrible at giving clear examples of how to connect with .NET.
One key thing I finally realized is that you can either connect using an OAuth2 credential or a service account credential. If you own your Analytics account, use a service account. If you're needing to connect to other users' Analytics accounts, use OAuth2.
There seem to be quite a few examples online of how to get Analytics API data using an OAuth2 credential, but I own my Analytics account and just wanted to pull data from it. I figured out how to connect to the Analytics Reporting API v4 using a ServiceAccountCredential, and I wrote an answer on a similar Stack Overflow question with all the details.
Here Is the code you actually looking for-
protected void Page_Load(object sender, EventArgs e)
{
IRestRequest request = new RestRequest("", Method.POST, DataFormat.Json);
string url = "https://analyticsreporting.googleapis.com/v4/reports:batchGet";
RestClient restClient = new RestClient();
RestRequest Tokenrequest = new RestRequest();
Tokenrequest.AddQueryParameter("client_id", "<CLIENTID>");
Tokenrequest.AddQueryParameter("client_secret", "<CLIENTSECRET>");
Tokenrequest.AddQueryParameter("grant_type", "refresh_token");
Tokenrequest.AddQueryParameter("refresh_token", "<REFRESH_TOKEN>");
restClient.BaseUrl = new System.Uri("https://oauth2.googleapis.com/token");
restClient.Post(Tokenrequest);
var responseToken = restClient.Execute(Tokenrequest);
//Response.Write(responseToken);
dynamic Tokendata = JObject.Parse(responseToken.Content);
var newToken = Tokendata.access_token.Value;
request.AddHeader("authorization", string.Concat("Bearer "+newToken));
string jsonString = "{" +
"\"reportRequests\": [{" +
"\"dateRanges\" : [{\"" +
"startDate\" :'2021-07-01' ," +
"\"endDate\" : '2021-07-07'" +
"}]," +
"\"metrics\":["+
"{\"expression\":'ga:totalEvents'},"+
"{\"expression\": 'ga:pageviews'}"+
"]," +
"\"dimensions\": ["+
"{\"name\": 'ga:eventCategory'}" +
",{" +
"\"name\": 'ga:eventAction'"+
"},"+
//"{\"name\": 'ga:deviceCategory'}"+
"]," +
"\"dimensionFilterClauses\": [{"+
"\"filters\": [{"+
"\"dimensionName\": 'ga:eventCategory',"+
"\"operator\": 'EXACT',"+
"\"expressions\": ["+
"\"Login_Form"+
"\"]}]}],"+
"\"viewId\":'<VIEWID>'" +
"}]" +
"}";
IRestClient client = new RestClient(url);
request.AddHeader("Content-Type", "application/json; CHARSET=UTF-8");
request.Resource = "";
request.AddParameter("application/json", jsonString, ParameterType.RequestBody);
var response = client.Execute(request);
dynamic jdata = JObject.Parse(response.Content);
var Row_data = jdata.reports[0].data.rows;
Response.Write(Row_data);
}
Read The Document To Get access_token through refresh_token.
https://developers.google.com/identity/protocols/oauth2/web-server#offline
Related
I want to develop a console application that pulls all campaigns under adwords accounts using Google Ads Api.
But I could not pass the authentication step.
I do not fully understand whether I should use the Service Account or Desktop Application Flow for this process.
GoogleAdsConfig config = new GoogleAdsConfig()
{
DeveloperToken = "Dev_token",
OAuth2Mode = Google.Ads.GoogleAds.Config.OAuth2Flow.APPLICATION,
OAuth2ClientId = "client_Id",
OAuth2ClientSecret = "secrret",
OAuth2RefreshToken = " refresh_token",
};
GoogleAdsClient client = new GoogleAdsClient(config);
GoogleAdsServiceClient googleAdsService = client.GetService(Google.Ads.GoogleAds.Services.V10.GoogleAdsService);
googleAdsService.SearchStream(AdwordsClientId, query,
delegate (SearchGoogleAdsStreamResponse resp)
{
foreach (GoogleAdsRow adsRow in resp.Results)
{
}
}
);
When I try as above, I get the following error
Google.Apis.Auth.OAuth2.Responses.TokenResponseException: Error:"unauthorized_client", Description:"Unauthorized", Uri:""
What paths should i follow?
Thank you.
unauthorized_client could have a couple of reasons. The most important ones that come to mind:
Did you make sure that your client ID and client secret match?
Have you activated the Google Ads API for the GCP project whose OAuth2 client you are using?
I'm working on a ASP.NET MVC 5 with Entity Framework (version 6.0) application.
I have added the simple google login, that saves the google email with the user on registration. How do I also get the profile picture of the Google+ user when they login and cast it in a view?
Google Plus API for developers allows you to fetch public data from Google+.
Followed by detail tutorial of all the necessary steps one need to perform to successfully fetch public data from Google+.
Google implies a limit to the usage of Google+ API - Each developer has a quota. We will see about that when we will discuss Google API console.
Google uses OAuth2.0 protocol to authorize your application when it tries to access user data.
It mostly uses standard HTTP method by means of RESTful API design to fetch and manipulate user data.
Google uses JSON Data Format to represent the resources in the API.
Step1: Generate an API key through Google API Console.
Step2: used GoogleOAuth2AuthenticationOptions which means you'll need to set
up a project at https://console.developers.google.com/project first to get a ClientId and ClientSecret.
At that link (https://console.developers.google.com/project), create a project and then select it.
Then on the left side menu, click on "APIs & auth".
Under "APIs", ensure you have "Google+ API" set to "On".
Then click on "Credentials" (in the left side menu).
Then click on the button "Create new Client ID".
Follow the instructions and you will then be provided with a ClientId and ClientSecret, take note of both.
var googleOptions = new GoogleOAuth2AuthenticationOptions()
{
ClientId = [INSERT CLIENT ID HERE],
ClientSecret = [INSERT CLIENT SECRET HERE],
Provider = new GoogleOAuth2AuthenticationProvider()
{
OnAuthenticated = (context) =>
{
context.Identity.AddClaim(new Claim("urn:google:name", context.Identity.FindFirstValue(ClaimTypes.Name)));
context.Identity.AddClaim(new Claim("urn:google:email", context.Identity.FindFirstValue(ClaimTypes.Email)));
//This following line is need to retrieve the profile image
context.Identity.AddClaim(new System.Security.Claims.Claim("urn:google:accesstoken", context.AccessToken, ClaimValueTypes.String, "Google"));
return Task.FromResult(0);
}
}
};
app.UseGoogleAuthentication(googleOptions);
//get access token to use in profile image request
var accessToken = loginInfo.ExternalIdentity.Claims.Where(c => c.Type.Equals("urn:google:accesstoken")).Select(c => c.Value).FirstOrDefault();
Uri apiRequestUri = new Uri("https://www.googleapis.com/oauth2/v2/userinfo?access_token=" + accessToken);
//request profile image
using (var webClient = new System.Net.WebClient())
{
var json = webClient.DownloadString(apiRequestUri);
dynamic result = JsonConvert.DeserializeObject(json);
userPicture = result.picture;
}
OR
var info = await signInManager.GetExternalLoginInfoAsync();
var picture = info.ExternalPrincipal.FindFirstValue("pictureUrl");
ExternalLoginCallback method I check for which login provider is being used and handle the data for Google login.
Go through the link to get more information.
https://developers.google.com/identity/protocols/OAuth2
I have tried it its working.
I am trying to use box api in an asp.net web application.
Based on the search there are two options to access box account;
By downloading the Box.V2 package using below link containing the required dlls and use that in our application
By using Box SDK containing code and reference that inside our application. Using this approach we can debug the Box.V2 code by adding the project to our solution.
Correct me if I am wrong.
So, I am trying to implement the second approach. Can someone help me move forward by specifying the steps to be taken, minimum .net framework requirement, etc.
Good question, GitHub samples does not mention about the Web (Asp.Net).
It's possible and it looks pretty easy to do once you figure out the the way,
I have seen some answers for Windows apps trying to manually build the authorization URLs etc, but there is an easier way to do it.
Here's how to do it with OAuth,
Install nuget
PM> Install-Package Box.V2
Get the Authcode (this is what's been missing in most examples)
public async Task<ActionResult> Connect()
{
var clientId = "xxxxx";
var clientSecret = "xxxxxx";
var redirectUri = new Uri("http://localhost:xxxx/Home/AuthCallBackAsync");//Your call back URL
var config = new BoxConfig(clientId, clientSecret, redirectUri);
return Redirect(config.AuthCodeUri.ToString());
}
Interesting thing is that the "config" object generates the AuthCodeUri.
This will redirect the user to Consent screen and ask the user to sign in. Once the user "Grants Access" you will get the "Authcode" for your call back URL which can be used to generate accesstoken.
Handle the Auth Callback response
public async Task<ActionResult> AuthCallbackAsync()
{
NameValueCollection parms = Request.QueryString;
var authCode = parms["code"]
//Get "config" - you can store this in session or in a cache.
var config = new BoxConfig(clientId, clientSecret, redirectUri);
var client = new BoxClient(config);
await client.Auth.AuthenticateAsync(authCode);
//Now you will get the accesstoken and refresh token
var accessToken = client.Auth.Session.AccessToken;
var refreshToken = client.Auth.Session.RefreshToken;
//Ready to consume the API
var user = await client.UsersManager.GetCurrentUserInformationAsync();
-------More Api Calls---
}
I am tring to write to Freebase using MQLWrite.
I manage to write using the Freebase Query.
I enter the url and get an error saying
Login is Required
I am using C#.
another thing to mention is I do not need a user consent. I created a service account in Google Developer console, and tried using the following code from this url:
https://code.google.com/p/google-api-dotnet-client/source/browse/Plus.ServiceAccount/Program.cs?repo=samples&r=406dd0081ca556a81621b910eac4445e3309ad1e&spec=svn.samples.406dd0081ca556a81621b910eac4445e3309ad1e
public class Program
{
// A known public activity.
private static String ACTIVITY_ID = "z12gtjhq3qn2xxl2o224exwiqruvtda0i";
public static void Main(string[] args)
{
Console.WriteLine("Plus API - Service Account");
Console.WriteLine("==========================");
String serviceAccountEmail = "SERVICE_ACCOUNT_EMAIL_HERE";
var certificate = new X509Certificate2(#"key.p12", "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { PlusService.Scope.PlusMe }
}.FromCertificate(certificate));
// Create the service.
var service = new PlusService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Plus API Sample",
});
Activity activity = service.Activities.Get(ACTIVITY_ID).Execute();
Console.WriteLine(" Activity: " + activity.Object.Content);
Console.WriteLine(" Video: " + activity.Object.Attachments[0].Url);
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
}
I do not what ACTIVITY_ID means, is that the same as CLIENT_ID?
In the above example they use plus but i want to use Freebase and cannot find the scope property any where in the namespace.
Appreciate any kind help... :)
From documentation:
MQL Write requires Authorization. Make sure your authentication is working correctly.
Your application must use OAuth 2.0 to authorize requests. No other authorization protocols are supported.
Using MQL Write
MQL Write supports legacy developer applications that write to
Freebase. In order to use MQL Write, developers must contact Freebase
and request additional quota using the MQL Write Quota Access Request
form.
I have been able to get access with Public Access key only so far.
// Simple API example
// Public API access = is from developer console its different then OAuth. (its at the bottom)
var service = new FreebaseService(new BaseClientService.Initializer
{
ApplicationName = "Discovery Sample",
ApiKey = "{Public API access}",
});
The Nuget package appears to be missing Google.Apis.Auth which is used for OAuth access. Either the API doesn't support Oauth access which cant be since the documentation states you need Oauth to access the write features. Or there is something wrong with the NuGet package.
Can you try and run your write against this? See if it works or not.
Probably not the only one asking this, but I found nothing that works...It's like a jungle ;)
I have a C# desktop app (5-10 user) that I want to connect to my Google calendar. I want to add, move, delete, update events in the calendar. I downloaded an installed the last .Net api v.3.
From what I read, the difficult part is the authenticate/connecting procedure. I suppose that we need to use OAuth 2.0 authentication ? I want my user to authenticate once, not each time they want to make a action (add, move, delete, update).In some sample I get we have to cut and paste a token from a web page into a Console...not really user friendly. And how to authenticate only 1 times (or just put the token directly in code to not authenticate ?) ?
Now, were I can have a good working sample code in C# to make that ?
Thanks you very much for helping !!
I used something similar to the example here. What I did initially was create a simple web application using the sample logic to setup the initial auth that Google requires. I stepped through and got the Refresh Token from the state. I then saved this in an app setting that I could use later during future GetAuthorization requests. At least for what I was doing this worked well, the user never needed to authorize as long as app stayed connected.
private IAuthorizationState GetAuthorization(WebServerClient client)
{
IAuthorizationState state = new AuthorizationState(new[] { CalendarService.Scopes.Calendar.GetStringValue() });
string refreshToken = LoadRefreshToken();//this where I wrote code to load it from the app settings
if (!string.IsNullOrEmpty(refreshToken))
{
state.RefreshToken = refreshToken;
try
{
if (client.RefreshToken(state))
return state;
}
catch (ProtocolException)
{
return null;
}
}
return null;
}
I have today the same issue and found now the solution
Prepare Api Access https://console.developers.google.com/apis/dashboard
Press button "Enable Apis and services"
Search "Calendar" and choose "Google Calendar API"
Press button "Create Project"
Create Project
Press "Enable"
Press button "Create credentials"
Choose "Where will you be calling the API from?" -> Other UI
Choose "What data will you be accessing?" -> Application data
Create service account
Choose Role Project -> Editor
Choose Key type JSON
Press button "Continue"
Rename the file to "credential.json" and save it in the visual studio project
Change in Visual Studio the Copy to output Directory -> "Copy if newer"
Change share config of your google calendar (Share this Calendar)
Add the email address from the json file "client_email" in the google calendar config "Share with specific people"
Example Code
using Google.Apis.Auth.OAuth2;
using Google.Apis.Calendar.v3;
using Google.Apis.Calendar.v3.Data;
using Google.Apis.Services;
using System.IO;
namespace Test.GoogleCalendar
{
class Program
{
static void Main(string[] args)
{
GoogleCredential credential;
using (var stream = new FileStream("credential.json", FileMode.Open, FileAccess.Read))
{
credential = GoogleCredential.FromStream(stream).CreateScoped(CalendarService.Scope.Calendar);
}
// Create Google Calendar API service.
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Test Calendar Reader",
});
var calendars = service.CalendarList.List().Execute().Items;
foreach (CalendarListEntry calendar in calendars)
{
var events = service.Events.List(calendar.Id).Execute();
}
}
}
}
Here is a link to help download Calendar Client API library for .NET. The library makes OAuth and accessing the Calendar easier. See link for OAuth details but I'm pretty sure it's what you want - user logs in only once to authorize.
On same page there are sample applications using the Client API in VB.NET and MVC.