I wonder if anyone has got any further than me using the new Search Analytics functions of the Google Webmaster Tools API via .Net?
I am using the Google.Apis.Webmasters.v3 Nuget package and have got as far as authenticating and connecting (using a Service Account)
However I'm struggling to get anywhere with Search Analytics.
I couldn't find any code samples online so have been guided by the Class info at https://developers.google.com/resources/api-libraries/documentation/webmasters/v3/csharp/latest/annotated.html and a lot of guesswork.
Here is the code I am using:
SearchanalyticsResource mySearchanalyticsResource = new SearchanalyticsResource(service);
SearchAnalyticsQueryRequest myRequest = new SearchAnalyticsQueryRequest();
myRequest.StartDate = "2015-08-01";
myRequest.EndDate = "2015-08-31";
myRequest.RowLimit = 10;
SearchanalyticsResource.QueryRequest myQueryRequest = mySearchanalyticsResource.Query(myRequest, site.SiteUrl);
SearchAnalyticsQueryResponse myQueryResponse = myQueryRequest.Execute();
It runs OK until the Execute method when I get "An Error occurred, but the error response could not be deserialized". Exception detail below...
Newtonsoft.Json.JsonReaderException {"Error parsing NaN value. Path '', line 0, position 0."}
Any help or code samples would be very gratefully received!
This compiles but its not returning any data for me.
Auth:
public static WebmastersService WMAuthenticateOauth(string clientId, string clientSecret, string userName)
{
string[] scopes = new string[] { WebmastersService.Scope.Webmasters }; // View analytics data
try
{
// here is where we Request the user to give us access, or use the Refresh Token that was previously stored in %AppData%
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets { ClientId = clientId, ClientSecret = clientSecret }
, scopes
, userName
, CancellationToken.None
, new FileDataStore(".", true)).Result;
WebmastersService service = new WebmastersService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "WebMasters API Sample",
});
return service;
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException);
return null;
}
}
Request
var service = Authentcation.WMAuthenticateOauth(clientid, secret, "testmmm");
IList<string> newlist = new List<string> ();
newlist.Add("country");
newlist.Add("device");
SearchAnalyticsQueryRequest body = new SearchAnalyticsQueryRequest();
body.StartDate = "2015-04-01";
body.EndDate = "2015-05-01";
body.Dimensions = newlist;
var result = service.Searchanalytics.Query(body, "http://www.daimto.com/").Execute();
I have also tried testing using the try me at the bottom of this page. It doesn't return anything either.
Strange API this.
Update:
I finally got data back I set the dates to
body.StartDate = "2015-09-01";
body.EndDate = "2015-09-15";
I wonder if this thing has limited data, it only goes back so far.
Related
Environment: ASP.NET simple web application on .net 4.5.1 integrated pipeline running on iis8 on server 2012 which is not following MVC.
I'm attempting to get credentials from google's GoogleWebAuthorizationBroker but i keep getting "access is denied"...Even i allowed my urls in "Authorized JavaScript origins" and "Authorized redirect URIs"
Following below URL implementation for Installed App
https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth#installed-applications
Here are mine code snippet
var folder = "F:\\MyApp\\WebApp\\MyGoogleStorage";
string[] scopes = new string[] {
Google.Apis.Proximitybeacon.v1beta1.ProximitybeaconService.Scope.UserlocationBeaconRegistry
};
ClientSecrets secrets = new ClientSecrets()
{
ClientId = CLIENT_ID,
ClientSecret = CLIENT_SECRET
};
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
secrets,
scopes,
"user",
CancellationToken.None,
new FileDataStore(folder)).Result;
And use another way to create credentials
using (var stream = new FileStream(Utility.AppPath + "/client_secrets.json", FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
scopes,
"user", CancellationToken.None, new FileDataStore(folder));
}
But in both cases i am getting access denied.
My assumption is that, it's happening because i am trying to use sample
"Installed Applications"
Please advice me what is the best way to do that in .net simple web application.
Also share some code if any one done it successfully.
Thanks in advance..!!!
For this solution work around I found was
string serviceAccountEmail = "proximitybeacon#proximitytest-1234.iam.gserviceaccount.com"; // Service Account Email
string userEmail = "abc#gmail.com"; //Email of yours
//.p12 file is having all the details about the Service Account we create a Cryptography certificate by it. This you need to download fron your project which you make in Google Developer Console. Foolow stesps from this link https://webapps.stackexchange.com/questions/58411/how-where-to-obtain-a-p12-key-file-from-the-google-developers-console
X509Certificate2 certificate = new X509Certificate2("F://yorrappPath/ProximityTest-2d889bd4fa49.p12", "notasecret", X509KeyStorageFlags.Exportable); // F://yorrappPath -- Give proper location of .p12 file
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
User = userEmail,
Scopes = new string[] { "https://www.googleapis.com/auth/userlocation.beacon.registry" }
}.FromCertificate(certificate));
if (!credential.RequestAccessTokenAsync(CancellationToken.None).Result)
{
return "Can't get the access token";
}
//Beacon Object with its values
Google.Apis.Proximitybeacon.v1beta1.Data.Beacon beacon = new Google.Apis.Proximitybeacon.v1beta1.Data.Beacon();
Google.Apis.Proximitybeacon.v1beta1.Data.AdvertisedId advertisedId = new Google.Apis.Proximitybeacon.v1beta1.Data.AdvertisedId();
beacon.AdvertisedId = new Google.Apis.Proximitybeacon.v1beta1.Data.AdvertisedId() { Id = "ZgCC7BLy8FXla3VmnnibWQ==", Type = "EDDYSTONE" };
beacon.BeaconName = "99911";
beacon.Status = "ACTIVE";
beacon.LatLng = new Google.Apis.Proximitybeacon.v1beta1.Data.LatLng() { Latitude = 28.38, Longitude = 77.12 };
beacon.ExpectedStability = "STABLE";
//Beacon Service for register which having HttpClientInitializer(credential with token detail)
Google.Apis.Proximitybeacon.v1beta1.ProximitybeaconService service = new Google.Apis.Proximitybeacon.v1beta1.ProximitybeaconService(new BaseClientService.Initializer()
{
ApplicationName = "proximityTest", // Replace that with you App name which you given in Google
HttpClientInitializer = credential
});
var registerRequest = new Google.Apis.Proximitybeacon.v1beta1.BeaconsResource.RegisterRequest(service, beacon);
//uncomment this for update beacons. 3 parameter is important for update BeaconName
//var updateRequest = new Google.Apis.Proximitybeacon.v1beta1.BeaconsResource.UpdateRequest(service, beacon, "beacons/3!660082ec12f2f055e56b75669e789b59");
//updateRequest.Execute();
//uncomment this for getting list of beacons.
// var listRequest = new Google.Apis.Proximitybeacon.v1beta1.BeaconsResource.ListRequest(service);
// return listRequest.Execute();
try
{
//This will register a Beacon
registerRequest.Execute();
}
catch (Exception ex)
{
return ex.Message;
}
return beacon;
I have been using the Google.GData.Analytics and Google.GData.Client
to retrieve some Google Analytics data though the Google Analytics API v2 in my web application.
The code was as follows:
string username = "abc#gmail.com";
string password = "myPasswordHere";
string profileId = "ga:88376970";
string _from = Convert.ToDateTime(dtpFrom.SelectedDate.Value.ToString()).ToString("yyyy-MM-dd");
string _to = Convert.ToDateTime(dtpTo.SelectedDate.Value.ToString()).ToString("yyyy-MM-dd");
AccountQuery AccountsQuery = new AccountQuery();
service = new AnalyticsService("DoogalAnalytics");
service.setUserCredentials(username, password);
try
{
DataFeedUrl = "https://www.google.com/analytics/feeds/data";
DataQuery PageViewQuery = new DataQuery(DataFeedUrl)
{
Ids = profileId ,
Metrics = "ga:pageviews",
Dimensions = "ga:date",
Sort = "ga:date",
GAStartDate = _from,
GAEndDate = _to
};
StringBuilder strData = new StringBuilder();
int maxValue = 0;
int today = 0;
List<int> gList = new List<int>();
foreach (DataEntry entry in service.Query(PageViewQuery).Entries)
{
var value = entry.Metrics.First().IntegerValue;
gList.Add(value);
maxValue = value > maxValue ? value : maxValue;
today = entry.Metrics.Last().IntegerValue;
strData.AppendFormat("{0},", value);
}
}
catch (Exception ex)
{
Response.Write(ex.Message.ToString());
}
This code was working perfectly fine until about 5 days ago and I have been using this code for the last 7 or 8 months, but now suddenly I am facing the error
Execution of authentication request returned unexpected result: 404.
When I searched google.
I have searched alot but could not find any solution.
Any help or guidance will be greatly appreciated.
Client login which was discontinued / shutdown began on April 20 2015 and probably completed around May 26 2015. You can no longer use client login (Login and password) with the Google Analytics API, you need to switch to Oauth2. You will need to change your code to use Oauth2 or a service account.
Its best to grab the newest version of the client library which uses Google Analytics V3 you are using V2.
PM> Install-Package Google.Apis.Analytics.v3
If this is data you already own you may want to consider a service account. A service account will let you set up access to your google analytics account and it wont require a user to authenticate your code. If this is not your Google Analytics account but in fact one owned by another user then you will need to use Oauth2 and request authentication from the user.
My Tutorial: Google Analytics API Authentication with C#
Code ripped from tutorial above the tutorial is kept up to date this code may not be:
string[] scopes = new string[] {
AnalyticsService.Scope.Analytics, // view and manage your Google Analytics data
AnalyticsService.Scope.AnalyticsEdit, // Edit and manage Google Analytics Account
AnalyticsService.Scope.AnalyticsManageUsers, // Edit and manage Google Analytics Users
AnalyticsService.Scope.AnalyticsReadonly}; // View Google Analytics Data
String CLIENT_ID = "6.apps.googleusercontent.com"; // found in Developer console
String CLIENT_SECRET = "xxx";// found in Developer console
// here is where we Request the user to give us access, or use the Refresh Token that was previously stored in %AppData%
UserCredential credential =
GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets {
ClientId = CLIENT_ID
, ClientSecret = CLIENT_SECRET
}
, scopes
, Environment.UserName
, CancellationToken.None
, new FileDataStore("Daimto.GoogleAnalytics.Auth.Store")).Result;
AnalyticsService service = new AnalyticsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Analytics API Sample",
});
DataResource.GaResource.GetRequest request = service.Data.Ga.Get("ga:8903098", "2014-01-01", "2014-01-01", "ga:sessions");
request.MaxResults = 1000;
GaData result = request.Execute();
I have been using the old version of Google Calendar GData API (v1, v2) since November 2011 in my ASP.NET Applications, allowing Users to retrieve and/or create Calendar Events after submitting their usernames and passwords , and this was working perfectly till 17th of November 2014 just before Google decided to shut down this version of API as announced Calendar GData API / Google Calendar Connectors deprecation
Now I am stuck with the new version of Google APIS Calendar (v3) which forces me to use different scenario of Authentication Process instead of the Traditional one. I don't mind at all using this version of Calendar API as it supports all the needed features but now i don't know how to handle multiple users authentication to use their User Client's ID and Secret which are registered per each user Code Console.
So my question is : Is there any way to let user sign in with his/her normal credentials (Either by Username/Password or Google+ Sign UP feature) and bypassing the process of creating API Project, Enabling the needed APIs and creating new User credentials inside the Console through ASP.net code?
Any Sample code made in C# ASP.net is highly appreciated .
EDIT: Here is my code of Authentication I use
public static CalendarService Authenticate()
{
CalendarService service;
GoogleAuthorizationCodeFlow flow;
string json_File = System.Configuration.ConfigurationManager.AppSettings["Authentication_Path"];
string store_path = System.Configuration.ConfigurationManager.AppSettings["FileStore_Path"];
string url = System.Configuration.ConfigurationManager.AppSettings["Authent_URL"];
using (var stream = new FileStream(json_File, FileMode.Open, FileAccess.Read))
{
flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
DataStore = new FileDataStore(store_path),
ClientSecretsStream = stream,
Scopes = new[] { CalendarService.Scope.Calendar }
});
}
var uri = url;
var result = new AuthorizationCodeWebApp(flow, uri, uri).AuthorizeAsync("TRAININGCALENDAR", CancellationToken.None).Result;
if (result.Credential == null)
{
GoogleCalendar_Bus.Main_Authentication(url, "", "");
}
// The data store contains the user credential, so the user has been already authenticated.
service = new CalendarService(new BaseClientService.Initializer
{
ApplicationName = "Calendar API Sample",
HttpClientInitializer = result.Credential
});
if (result.Credential != null)
{
service = new CalendarService(new BaseClientService.Initializer
{
ApplicationName = "Calendar API Sample",
HttpClientInitializer = result.Credential
});
}
return service;
}
No you need to use Oauth2. When they authenticate you just save the refresh token this will allow you to then get a new access token and you will have access again. You will need to make your own implementation of Idatastore to store these refresh tokens in the database.
The code for creating an implementation of a Idatastore that stores to the Database is to extensive to post here but you can see a basic example here: DatabaseDataStore.cs
Then you can use it like this.
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets { ClientId = _client_id
,ClientSecret = _client_secret }
,scopes
,Environment.UserName
,CancellationToken.None
,new DatabaseDataStore(#"LINDAPC\SQL2012", "LindaTest", "test123", "test", "test")).Result;
Update: Now that I can see your code.
Make sure you have the latested .net client lib. Google.Apis.Calendar.v3 Client Library
your code is using FileDataStore this is what you will need to change. You need to make your own implementation of Idatastore similar to the one I have created DatabaseDatastore.
Your code looks different from how I normally do it.
string[] scopes = new string[] {
CalendarService.Scope.Calendar , // Manage your calendars
CalendarService.Scope.CalendarReadonly // View your Calendars
};
try
{
// here is where we Request the user to give us access, or use the Refresh Token that was previously stored in %AppData%
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets { ClientId = clientId, ClientSecret = clientSecret }
, scopes
, userName
, CancellationToken.None
, new FileDataStore("Daimto.GoogleCalendar.Auth.Store")).Result;
CalendarService service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Calendar API Sample",
});
return service;
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException);
return null;
}
This may be due to the fact that you aren't using the most up to date client lib, you can find a sample console application for Google Calendar here unfortunately it also uses FileDatastore you will have to edit it to use DatabaseDataStore. The authentication sample project can be found here Google-Dotnet-Samples/Authentication/ it shows how you can create your own implementation of Idatastore.
I am still working on the tutorial to go along with that sample project I hope to have it completed soon.
I have to perform a very simple task to get all the tasks of the account Google through Google Api.
Before i started this questions i read documentation, try search to answers, read tech forums, etc
First of all, I configured Developers Console:
- turned ON required API's: such as Tasks API
- Create and download to my project all generic keys: WEB, SERVICE + P12 KEY, INSTALL APP
- also, Installed in project all requiered Nugets: Auth, Client, Core, Tasks.v1
May be i wrong, but matter of great concern (Common Questions):
1. Why need too many variants of keys?
Google IP is only service and it shall be necessary only one token (key)
For software there is no fundamental difference between back-end, desktop, desktop on IOS/Android/Blackberry, service,...
Software need only get/set data from/to some Google Account.
It's very confuse.
2. Google Developers Console - is not simple and clear tools for ordinal user which want get ability to sync with google apps.
Why Google not have simple trust Token generation for account ?
3. Google documentation is not fully and complex. Too many blank places: such as REST queries - not see any correct and work samples with test data and headers.
May any known - where it is ?
Ok, let's begin practice - simple Desktop app on VS2012:
4. Most of google samples said that i need to use GoogleWebAuthorizationBroker
The Code below is similar as all codes in documenation
client_secret.json - JSON files from Google Developers Console
I were try all JSON files with secret codes and also manually set secrets
But nothing, GoogleWebAuthorizationBroker.AuthorizeAsync try to open bad browser window and ends
UserCredential credential;
var stream = new FileStream(#"..." + client_secret.json, FileMode.Open, FileAccess.Read);
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
new[] { TasksService.Scope.Tasks },
"user",
CancellationToken.None,
new FileDataStore("Tasks.Auth.Store")).Result;
// Create the service.
var service = new TasksService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Api Project"
});
TaskLists results = service.Tasklists.List().Execute();
What is Wrong ???
5. Ок, try to use this:
GoogleAuthorizationCodeFlow flow;
using (var stream = new FileStream(#"..." + client_secret.json, FileMode.Open, FileAccess.Read))
{
flow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
DataStore = new FileDataStore("Tasks.Auth.Store"),
ClientSecrets = GoogleClientSecrets.Load(stream).Secrets,
Scopes = new[] { TasksService.Scope.Tasks }
});
}
var result = new AuthorizationCodeWebApp(flow, "", "")
.AuthorizeAsync("user_id", CancellationToken.None).Result;
// The data store contains the user credential, so the user has been already authenticated.
TasksService service = new TasksService(new BaseClientService.Initializer
{
ApplicationName = "API Project",
HttpClientInitializer = result.Credential
});
var lists = service.Tasklists.List().Execute();
Always - not auth.
I was try changed "user_id" - but nothing
What is wrong ???
5. Ок, try to use this:
string serviceAccountEmail = "xxx#developer.gserviceaccount.com";
var certificate = new X509Certificate2(#"...\\key.p12", "notasecret", X509KeyStorageFlags.Exportable);
//var certificate = new X509Certificate2(#"key.p12", "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { TasksService.Scope.Tasks }
}.FromCertificate(certificate));
// Create the service.
var service = new TasksService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "API Project",
});
var lists = service.Tasklists.List().Execute();
if (lists.Items != null)
{
foreach (TaskList lst in lists.Items)
{
var title = lst.Title;
var tasks = service.Tasks.List(lst.Id).Execute();
if (tasks.Items != null)
{
foreach (Task tsk in tasks.Items)
{
}
}
}
}
!!! I have access, but not for my account.
Google return only one EMPTY enemy task list (NOT my 2 lists with many tasks in my account)
What is wrong ???
P.S. Please help. I am in deadlock. I did not expect that Google so bad.
Please, do not redirect me to another forums or topics. I all read before.
Thanks
I'm trying to write a simple command line application that will upload a file to Google Drive. I'm following along with the steps provided here: https://developers.google.com/drive/web/quickstart/quickstart-cs
The sample code they provide doesn't compile, specifically the line:
var service = new DriveService(new BaseClientService.Initializer()
{
Authenticator = auth
});
This returns the error:
"'Google.Apis.Services.BaseClientService.Initalizer' does not contain a definition for 'Authenticator'"
obviously the APIs have changed but I can't find the new way to do this.
First off you are missing the autentication code. Also the tutorial you are refering to uses an older version of the libary if you are using apis.drive.v2 that wont work. This one works with the newer libarys: My Tutorial Google Drive api C# (there is also a winform sample project)
But heres some Examples of how you can get it working:
UserCredential credential;
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets { ClientId = "YourClientId", ClientSecret = "YourClientSecret" },
new[] { DriveService.Scope.Drive,
DriveService.Scope.DriveFile },
"user",
CancellationToken.None,
new FileDataStore("Drive.Auth.Store")).Result; }
The code above will get you the User Credentials. It pops up a new browser window asking the user to autorise your app. My Tutorial here
BaseClientService service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Drive API Sample",
});
The code above allow you to access the Drive Service. See how we send it the credential that we got from the Oauth call? Then to upload its a matter of calling service.files.insert
// File's metadata.
File body = new File();
body.Title = "NewDirectory2";
body.Description = "Test Directory";
body.MimeType = "application/vnd.google-apps.folder";
body.Parents = new List<ParentReference>() { new ParentReference() { Id = "root" } };
try
{
FilesResource.InsertRequest request = service.Files.Insert(body);
request.Execute();
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}