Is there an API that allows access to Google's Mobile Friendly Test which can be seen at https://www.google.com/webmasters/tools/mobile-friendly/?
If you can't find one by googling, it probably doesn't exist.
A hacky solution would be to create a process with PhantomJS that inputs the url, submits it, and dirty-checks the dom for results.
PhantomJS is a headless WebKit scriptable with a JavaScript API.
However, if you abuse this, there is a chance that google will blacklist your ip address. Light use should be fine. Also be aware that google can change their dom structure or class names at any time, so don't be surprised if your tool suddenly breaks.
Here is some rough, untested code...
var url = 'https://www.google.com/webmasters/tools/mobile-friendly/';
page.open(url, function (status) {
// set the url
document.querySelector('input.jfk-textinput').value = "http://thesite.com";
document.querySelector('form').submit();
// check for results once in a while
setInterval(function(){
var results = getResults(); // TODO create getResults
if(results){
//TODO save the results
phantom.exit();
}
}, 1000);
});
There is an option in pagespeed api
https://www.googleapis.com/pagespeedonline/v3beta1/mobileReady?url={url}&key={api key}
key can be obtained form google cloud platform.
Acquire a PageSpeed Insights API KEY in https://console.developers.google.com/apis/api/pagespeedonline-json.googleapis.com/overview?project=citric-program-395&hl=pt-br&duration=P30D and create a credentials, follow the google's instructions.
In C# (6.0) and .NET 4.5.2, I did some like this:
(add in your project a reference for Newtonsoft.Json.)
String yourURL = "https://www.google.com.br";
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://www.googleapis.com");
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var response = client.GetAsync($"/pagespeedonline/v3beta1/mobileReady?url={yourURL }&key=AIzaSyArsacdp79HPFfRZRvXaiLEjCD1LtDm3ww").Result;
string json = response.Content.ReadAsStringAsync().Result;
JObject obj = JObject.Parse(json);
bool isMobileFriendly = obj.Value<JObject>("ruleGroups").Value<JObject>("USABILITY").Value<bool>("pass");
There is an API (Beta) for the Mobile Friendly-Test. (Release Date: 31.01.2017).
The API test outputs has three statuses:
MOBILE_FRIENDLY_TEST_RESULT_UNSPECIFIED Internal error when running this test. Please try running the test again.
MOBILE_FRIENDLY The page is mobile friendly.
3.NOT_MOBILE_FRIENDLY The page is not mobile friendly.
Here are more informations: https://developers.google.com/webmaster-tools/search-console-api/reference/rest/v1/urlTestingTools.mobileFriendlyTest/run
Related
I have a Web Api that invokes another web api call to get some information. In order to make the app more resilient, I implemented a HttpTransientErrorDetectionStrategy following the steps at: https://alexandrebrisebois.wordpress.com/2013/02/21/defining-an-http-transient-error-detection-strategy-for-rest-calls/
After that, I use code like below to invoke the other web app:
RetryPolicy _retryPolicy = new RetryPolicy<HttpTransientErrorDetectionStrategy>(
new ExponentialBackoff(retryCount: 2, minBackoff: TimeSpan.FromSeconds(0), maxBackoff: TimeSpan.FromSeconds(10), deltaBackoff: TimeSpan.FromSeconds(2)));
var _httpClient = new HttpClient
{
BaseAddress = new Uri("http://www.microsoft.com")
};
HttpResponseMessage response = _retryPolicy.ExecuteAsync(async () => await _httpClient.GetAsync($"", HttpCompletionOption.ResponseContentRead)).Result;
The _httpClient.GetAsync call gets stuck, and I have no idea why. If I remove the _retryPolicy, and just use _httpClient.GetAsync directly, it returns in a matter of seconds.
I have similar code on a console app, to invoke the same web app, and that is working fine, so this seems to be specific to the way I am using it in my web API. This is intended to be an app on Azure, but it happens when I debug locally as well. Does anybody have any idea why this is getting stuck? How can I debug this?
Thank you!
I have similar code on a console app, to invoke the same web app, and that is working fine, so this seems to be specific to the way I am using it in my web API.
The code you posted is blocking right here:
HttpResponseMessage response = _retryPolicy.ExecuteAsync(...).Result;
Don't block on async code. Instead, use await:
HttpResponseMessage response = await _retryPolicy.ExecuteAsync(...);
If I remove the _retryPolicy, and just use _httpClient.GetAsync directly, it returns in a matter of seconds.
If your original code is blocking, and you must block on asynchronous code (for some reason), then you can either use the ConfigureAwait(false) hack:
HttpResponseMessage response = _retryPolicy.ExecuteAsync(async () => await _httpClient.GetAsync($"", HttpCompletionOption.ResponseContentRead).ConfigureAwait(false)).Result;
or elide async/await:
HttpResponseMessage response = _retryPolicy.ExecuteAsync(() => _httpClient.GetAsync($"", HttpCompletionOption.ResponseContentRead)).Result;
P.S. Check out DecorrelatedJitterBackoffV2.
Is there any way to provide RedirectURL then using GoogleWebAuthorizationBroker?
Here is the sample code in C#:
Task<UserCredential> credential = GoogleWebAuthorizationBroker.AuthorizeAsync(secrets, scopes, GoogleDataStore.User, cancellationToken, dataStore);
Or we have to use different approach?
I have an "installed application" that runs on a user's desktop, not a website. By default, when I create an "installed application" project in the API console, the redirect URI seems to be set to local host by default.
What ends up happening is that after the authentication sequence the user gets redirected to localhost and receives a browser error. I would like to prevent this from happening by providing my own redirect URI: urn:ietf:wg:oauth:2.0:oob:auto
This seems to be possible using Python version of the Google Client API, but I find it difficult to find any reference to this with .NET.
Take a look in the implementation of PromptCodeReceiver, as you can see it contains the redirect uri.
You can implement your own ICodeReceiver with your prefer redirect uri, and call it from a WebBroker which should be similar to GoogleWebAuthorizationBroker.
I think it would be great to understand why can't you just use PrompotCodeReceiver or LocalServerCodeReceiver.
And be aware that we just released a new library last week, so you should update it to 1.9.0.
UPDATE (more details, Nov 25th 2014):
You can create your own ICodeReceiver. You will have to do the following:
* The code was never tested... sorry.
public class MyNewCodeReceiver : ICodeReceiver
{
public string RedirectUri
{
get { return YOU_REDIRECT_URI; }
}
public Task<AuthorizationCodeResponseUrl> ReceiveCodeAsync(
AuthorizationCodeRequestUrl url,
CancellationToken taskCancellationToken)
{
// YOUR CODE HERE FOR RECEIVING CODE FROM THE URL.
// TAKE A LOOK AT THE FOLLOWING:
// PromptCodeReceiver AND LocalServerCodeReceiver
// FOR EXAMPLES.
}
}
PromptCodeReceiver
and LocalServerCodeReceiver.
Then you will have to do the following
(instead of using the GoogleWebAuthorizationBroker.AuthorizeAsync method):
var initializer = new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = secrets,
Scopes = scopes,
DataStore = new FileDataStore("Google.Apis.Auth");
};
await new AuthorizationCodeInstalledApp(
new GoogleAuthorizationCodeFlow(initializer),
new MyNewCodeReceiver())
.AuthorizeAsync(user, taskCancellationToken);
In addition:
I'll be happy to understand further why you need to set a different redirect uri, so we will be able to improve the library accordingly.
When I create an installed application the current PromptCodeReceiver and LocalServerCodeReceiver work for me, so I'm not sure what's the problem with your code.
I am trying to use the Google Calendar API in .NET, specifically I am trying to get a list of events. According to the examples here, in different programming languages I need to create a 'service' object and an 'event' object. However, I can't find a clear explanation of what either of these objects is or how to initiate them. Does anyone have an explanation? Or can anyone provide any information or give me a link to where this is explained? It doesn't necessarily have to be in .NET
Here is the example in Java:
String pageToken = null;
do {
events = service.events().list('primary').setPageToken(pageToken).execute();
List<Event> items = events.getItems();
for (Event event : items) {
System.out.println(event.getSummary());
}
pageToken = events.getNextPageToken();
} while (pageToken != null);
Following the advice answered, I am getting the following error:
Could not load file or assembly 'Microsoft.Threading.Tasks.Extensions.Desktop, Version=1.0.16.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
Here is the code, the error occurs on the credentials = Await... line
Dim credential As UserCredential
Dim clientSecretsPath As String = Server.MapPath("~/App_Data/client_secret.json")
Dim scopes As IList(Of String) = New List(Of String)()
scopes.Add(CalendarService.Scope.Calendar)
Using stream = New System.IO.FileStream(clientSecretsPath, System.IO.FileMode.Open, System.IO.FileAccess.Read)
credential = Await GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets, scopes, "user", CancellationToken.None)
End Using
The problem with GoogleWebAuthorizationBroker is that it tries to launch a new instance of a web browser to go and get authorization where you have to click the "Grant" button.
Obviously if you're running a MVC project under IIS it's just going to get confused when the code tries to execute a web browser!
My solution:
Download the .net sample projects: https://code.google.com/p/google-api-dotnet-client/source/checkout?repo=samples
Build and run one of the projects relevant to you (Eg Calendar or Drive). Dont forget to include your client_secret.json file downloaded from the cloud console.
Run the project and it will open a new browser on your computer where you will have to click the "Grant" button. Do this once and then your MVC code will work because it will not try to open a web browser to grant the permissions.
I'm not aware of any other way to grant this permission to the SDK but it worked for me just great!
Good luck. This took me a good 5 hours to figure out.
Just had the same issue running VS2013 (using .net45 for my project):
After fetching the CalendarV3 API via NuGet you just have to manually add the reference to:
...packages\Microsoft.Bcl.Async.1.0.165\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll
to the project (because it is not inserted automatically via the NuGet-Script)!
That's it! Maybe #peleyal is correcting the script somewhen in future ;)
Remember that this sample is for Java. My recommendation is to do the following:
Take a look in our VB sample for the Calendar API which is available here
You should take a look also in other sample for C#, let's say Tasks API sample
Start a new project and add a NuGet reference to Google.Apis.Calednar.v3. Remember that it's prerelease version.
Your code should look like the following:
It's based on the 2 samples above, I didn't compile or test it but it should work.
UserCredential credential;
using (var stream = new System.IO.FileStream("client_secrets.json",
System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
new[] { CalendarService.Scope.Calendar },
"user", CancellationToken.None);
}
// Create the service.
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "YOUR APP NAME HERE",
});
var firstCalendar = (await service.CalendarList.List().ExecuteAsync()).Items().FirstOrDefault();
if (firstCalendar != null)
{
// Get all events from the first calendar.
var calEvents = await service.Events.List(firstCalendar.Id).ExecuteAsync();
// DO SOMETHING
var nextPage = calEvents.NextPage;
while (nextPage != null)
{
var listRequest = service.Events.List(firstCalendar.Id);
// Set the page token for getting the next events.
listRequest.PageToken = nextPage;
calEvents = await listRequest.EsecuteAsync();
// DO SOMETHING
nextPage = calEvents.NextPage;
}
}
I had the same error, and it was due to the app trying to launch the accept screen.
I first tried to get the vb.net example from google and ran that, which I did get to work, and change to my secret info, ran and got the accept screen. I then tried my app, and it still did not work.
I noticed that the dll was found here under my project installed from the nuget packages.
...packages\Microsoft.Bcl.Async.1.0.165\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll
but was not in the net45 dir. So I uninstalled the nuget packages (have to if changing the .net version) then changed my .net version for my project to 4.0 instead of 4.5, reinstalled the nuget packages, and then it worked!!
I have a service that is successfully deployed to Google Endpoints and it is accessible through browser.
Now I am trying to load Google API javascript client library to call my services using javascript.
As far as I know, I should do this
gapi.client.load([MY_APP_NAME], 'v1', function() {
var request = gapi.client.[API_NAME].[SERVICE_NAME].[METHOD]();
request.execute(function(jsonResp, rawResp) {...});
);
But I always get an exception at run time complaining about gapi.client.[MY_API_NAME] is undefined. I do the same thing with any Google API (such as Plus) and it works fine. For example, If I load 'plus' API, I will have access to gapi.client.plus... and I can call methods.
Am I missing something? All samples and documents are about Google Service APIs and I could not find a sample for custom APIs (the one that developers write).
I even tried gapi.client.request with different paths (absolute path and relative path) but I get 404 - Not Found error in "status".
var request = gapi.client.request({'path':
'https://[APP_NAME].appspot.com/_ah/api/[SERVICE_NAME]/v1/[METHOD]'
, 'method': 'GET'});
request.execute(function(jsonResp, rawResp) {...});
var request = gapi.client.request({
'path':'/[SERVICE_NAME]/v1/[METHOD]',
'method': 'GET'});
request.execute(function(jsonResp, rawResp) {...});
The problem was a missing parameter in calling gapi.client.load().
I looked at the definition of gapi.client.load at this link https://developers.google.com/api-client-library/javascript/reference/referencedocs#gapiclientload
gapi.client.load(name, version, callback)
which then later I found out is not totally correct and an optional parameter is missing (app_api_root_url).
gapi.client.load(name, version, callback, app_api_root_url)
If the app_api_root_url is missing, the client is loaded for Google Service APIs only (app_api_root_url such as https://myapp.appspot.com/_ah/api)
You can find more details on how to use gapi.client.load() properly at this link https://developers.google.com/appengine/docs/java/endpoints/consume_js
As you can see in the following piece of code, I didn't have ROOT parameter when I was calling gapi.client.load and that is why Google by default was looking at its own service API and obviously could not find my APIs.
var ROOT = 'https://your_app_id.appspot.com/_ah/api';
gapi.client.load('your_api_name', 'v1', function() {
var request = gapi.client.your_api_name.your_method_name();
request.execute(function(jsonResp, rawResp) {
//do the rest of what you need to do
});
}, ROOT);
NOTE: your_app_id is used in ROOT parameter only to load the client script. After loading is done, you will have an object that is named after your API and not your app. That object is like your Java (service) class and you can use to invoke methods directly.
I have an task to implement an chat based application to access private data available at server using web service api call.Show all available users from web server and to chat with those persons.Is't possible with titanium development to support on iPhone/Android chat application. If possible let me guide to implement the same.
Yes, of course it's possible. And there are a million ways to do this, your question is not very clear.
If its totally web services based then just use this.
Heres a quick example of posting to a webservice and sending a JSON object:
var getChatMessages = Ti.Network.createHTTPClient({
onload : function(e) {
var doSomethignWithThis = this.responseText;
},
onerror : function(e) {
Ti.API.info(this.responseText);
Ti.API.info('SelectActivityStepsByKeyList webservice failed with message : ' + e.error);
}
});
getChatMessages.open('POST', 'http://yourchatserver/GetChats');
getChatMessages.setRequestHeader("Content-Type", "application/json");
getChatMessages.send({"message" : "How is everyone today?", "user" : "me#me.com});
This is not difficult with titanium, the hard part is on the server side.
Here is an example project that accomplishes chat through the use of the socket.io library. This may be a better approach for you. The link has a video of how it works as well as the full source code.