Google Directions - different behaviour on different ISPs - javascript

we are using google maps service to fetch directions data between two points in dragdir format:
http://maps.google.com/maps?f=d&hl=en&saddr=43.2602841679131,16.6526985168457&daddr=43.5602841679131,16.7526985168457&ie=UTF8&0&om=0&output=dragdir
Issue we uncounted, manifests in a way that direction path for user connected to internet via particular ISP (ieg. t-com) is drawn or scaled or rotated or translated or with any combination of it.
Also, we use same pattern in android native apps and we had never bumped in such problems.
Do you maybe have any suggestion or good practice how avoid described problems?
Here is sample of dragdir json object returned from maps api:
{tooltipHtml:"
(151\x26#160;km / 1 hour 51 mins)",polylines:[{id:"route0",points:"e}ruGis|eBsGdPiBxJ{Ab
h#aAdKoDjNeDlHuC~Di#bBsAnPqAlGwDpGmDbCkGrO
aCzJ.. more scrambled data here ..?B",numLevels:4,zoomFactor:16}]}
Thank you!

I believe google is making region specific changes to the output.
I would suggest you to direct a call to your server and then call the google service from your server to get an uniform result.
See if you can also mention region in the google service calll itself.

If your page is being accessed from different parts of the world, it can very well cause the directions to be different. From the Region Biasing for Directions section of the Developer's Guide:
The Google Maps API Directions Service returns address results
influenced by the domain (region or country) from which you loaded the
JavaScript bootstrap. (Since most users load http://maps.google.com/
this sets an implicit domain to the United States.) If you load the
bootstrap from a different supported domain, you will get results
influenced by that domain. For example, searches for "San Francisco"
may return different results from applications loading
http://maps.google.com/ (the United States) than one loading
http://maps.google.es/ (Spain).
You can force Region Biasing by adding the following to your request URL parameters:
[after sensor=false, etc.] &region=US
This will set the Directions service to return results biased to a particular region (the USA in this case).

Related

Google places AutoComplete widget is generating a new Session Key per every request

Recently, Google has updated some billing policies as part of that they've introduced SessionTokens for the Autocomplete requests.
As part of that, every request in the same session will be sent the same token in the request and it's automatic if we use the AutoComplete widgets provided by Google APIs.
But, I'm seeing a different token generated for every request in the same session. I'm I missing anything, please guide me. Here is the pluker for the sample, there I observed a different token generated for each keystroke.
var options = {
types: ['(cities)']
};
var searchBox = new google.maps.places.Autocomplete(input, options);
My Code for the page
<div class="searchField">
<input id="searchLocation" name="searchLocation" type="text" placeholder="Enter an Address">
</div>
<!-- more code.... -->
<!-- footer -->
<script>
// initiate search area for autocomplete of places from Google Maps Street Addresses
function initAutocomplete() {
// define the search location box
var searchBox = $("#searchLocation")[0];
// initiate the autocomplete with the options on the search box
var autocomplete = new google.maps.places.Autocomplete(searchBox, options);
};
</script>
<script src="https://maps.googleapis.com/maps/api/js?libraries=places&region=ca&language=en&key= [YOUR_API_KEY]&callback=initAutocomplete" async defer>
</script>
Session Token Clarification
According to the Google Docs (all the way at the bottom of the page in a "warning text")...
https://developers.google.com/maps/documentation/javascript/places-autocomplete
Warning: Be sure to pass a unique session token for each new session.
Using the same token for more than one session will result in each
request being billed individually. Note that the Autocomplete Widget
handles sessions automatically (you don't need to do anything
additional). Now, lets dive into the basic Javascript example.
This may be a bit confusing, only because you are trying to get into the nomenclature of the google docs and what these things and possibly because you were doing it one way and suddenly your boss or client or someone else ask you to use Sessions/Session Tokens instead.
If you do new google.maps.places.Autocomplete() instead of AutocompleteServices or something along those lines, you are using the "Autocomplete Widget".
The autocomplete widget will handle the session / session tokens itself.
Prove it!
I trust Google and the Google Developer Documentation regarding their own products and how/what they do, but there was plenty of confusion on the web about this. So I wanted proof, besides getting a bill after a month. FYI - the billing in Google Clound Platform Console (https://console.cloud.google.com/google/maps-apis?pli=1) will show you this almost right away and will corroborate the stuff below and above.
Looking at the Network activity in Dev Tools, we see that there is a few calls to the Autocomplete Service.
I did not use the "AutocompleteService" function here, this is a basic example setup the same way I have listed above for the Callback with using the "Autocomplete Widget" via new google.maps.places.Autocomplete().
When you go to the page, you can see the call to library first, first screenshot of Dev Tools below.
Next I did a search, which worked. I started to type in a basic address of 1990, you can see 4 request made to the API after that. 1 request/call for each character I type in. Each of these request names begin with "AutocompleteServices.GetPredictions...", even though I DID NOT USE AutocompleteServices in my code. On the back-end, the "Autocomplete Widget" is using the "AutocompeleteServices" and doing all the UI/UX work for you as well as the functionality and the session and tokens. These are in the Dev tools screenshots #1-#3 below.
Then you see a 5th request call to "PlaceServces.GetPlaceDetails", which was when I selected from the dropdown. This is the dev tools screenshot #4 below.
Looking at the headers, for each of these requests, I see a few things.
The first thing, circled at the bottom is a "token". I know I just said and the Google Documentation just said that the "Autocomplete Widget" handles the session token, and a keen eye will see that this "token" value is different for every request. It is also not in 'version 4 UUID' format, which is recommended by Google, but that is a different topic. This "token" in the header, IS NOT the session token. This is buried in documentation that is 5 years old for a previous version of this on Google Docs, but this is not used anymore, and is auto-set for each request and is not the Session token.
SO, "where is the session token then?" you might ask.
The other items in the header that start with 1s, 2s and so on are different session variables that are passed. In this case, the session token is '20s' followed by the version 4 UUID auto created by the "Autocomplete Widget". A keen eye will also notice that for the 3 screenshots below they are the same. I have a fifth screenshot after the page refreshes that shows that the Session Token has changed. You can see in my code that I did not specify those things, but because I am using the "Autocomplete Widget" they are done for me.
I'm afraid token parameter that you can see in the request is not the places autocomplete session token. This parameter was there even before Google Maps platform changes. I don't know how Google manages handle autocomplete session tokens, probably they handle them server side.
The documentation states that autocomplete widget has automatic session tokens implemented.
Autocomplete (Web Service and JavaScript) and the JavaScript Autocomplete widget have been updated to use session-based billing.
Note: No code changes are required for the JavaScript Autocomplete widget, as the widget manages sessions for you automatically.
source: https://cloud.google.com/maps-platform/user-guide/pricing-changes/
To be sure I would suggest checking you billing reports in developer console.
https://console.cloud.google.com/billing/unbilledinvoice?project=YOUR_PROJECT_ID&authuser=1
In this report you will see which method was used for billing of places autocomplete requests. Have a look at rows where Product column is Places API and the Resource column will show which method was used for billing Autocomplete - Per Request or Autocomplete - Per Session.
If you use Place autocomplete widget with automatic sessions, but this report shows only usage of Autocomplete - Per Request reach out to Google maps technical support via https://console.cloud.google.com/google/maps-apis/support
If you use google.maps.places.Autocomplete(input, options); it will add session token automatically.
In your pluker example there is no Autocomplete but new google.maps.places.SearchBox

Programmatically get Gmail storage usage

How can I get the storage usage of Gmail programmatically? This value appears in two places, but I cannot find an API for it.
The main goal is to automatically log Gmail storage usage to a Google Sheet and graph the storage usage trend.
What I've tried:
DriveApp.getStorageUsed() does not include Gmail usage.
Reports API (gmail_used_quota_in_mb) is not available for consumer Gmail accounts (only G Suite)
Scraping www.google.com/settings/u/0/storage is not possible because a log-in is required, even when spoofing cookies (probably detects a new device/IP address).
Not the programmatic answer I am looking for, but this is my manual work-around until I discover an API method:
Examine the source code for google.com/settings/u/0/storage
Find exact bytes of usage embedded in JSON:
...
,[["Drive",["24004828","0.02 GB"]
]
,["Gmail",["4859735562","4.52 GB"]
]
,["Google Photos",["0","0 GB"]
...
Log that (4,859,735,562) into a Google Sheet, along with the current date/time
Using precise measurements of bytes and seconds, it should only take a few measurements to get an accurate trend. (And I don't need to scale this for multiple accounts.)
You can use Google Drive V2 API.
About: get returns quotaBytesByService[] where you can filter service by name (e.g. GMAIL, in your case)
If you want to use the API, you have to enable the advance API option and use it.
Note that the version 3 does not give you the service breakdown.

Google Maps JavaScript API RefererNotAllowedMapError

We're trying to develop an geoplacement app for one of our clients, and we want first to test it in out own domain.
We have signed for Google Maps JavaScript API, and we have a valid browser key and our domain, www.grupocamaleon.com, has been authorized to use that key.
But we can't make even the easiest example to run without error.
We have, in our domain and with our key, the following demo:
(1) http://www.grupocamaleon.com/boceto/aerial-simple.html
But it doesn't work, and Firebug console says:
"Google Maps API error: Google Maps API error: RefererNotAllowedMapError (link to Google documentation on RefererNotAllowedMapError) Your site URL to be authorized: (1)"
My credential page is missing the possibility of adding referrers to accept, so solutions involving adding referrers are not possible right now.
My credential Page:
Why do we get that error? How can we fix it?
I know this is an old question that already has several answers, but I had this same problem and for me the issue was that I followed the example provided on console.developers.google.com and entered my domains in the format *.domain.tld/*. This didn't work at all, and I tried adding all kinds of variations to this like domain.tld, domain.tld/*, *.domain.tld etc.
What solved it for me was adding the actual protocol too; http://domain.tld/* is the only one I need for it to work on my site. I guess I'll need to add https://domain.tld/* if I were to switch to HTTPS.
Update: Google have finally updated the placeholder to include http now:
Come on Google, you guys are smarter than the API Credential page lets on. (I know because I have two sons working there.)
The list of "referrers" is far pickier than it lets on. (Of course, it should be more forgiving.) Here are some rules that took me hours to discover:
The order in the list is important. Moving your URL up in the list may make it work.
"http://" prefix is required.
Even "localhost" needs it: "http://localhost/foo/bar.html"
A trailing * as a wildcard seems to work as if it is a string compare.
Even with "http://localhost/foo/bar.html", "http://localhost/foo/bar.html?arg=1" will not work. (Will a wildcard help?)
For both prod dev, have (at least) two rows: "http://localhost/foo/bar.html" and "http://my.site.com/foo/bar.html"
A port number (8085? 4000?) does not seem to be necessary.
There are probably other rules, but this is a tedious guessing game.
Wildcards (asterisks) ARE NOT allowed in the subdomain part.
WRONG: *.example.com/*
RIGHT: example.com/*
Forget what Google says on the placeholder, it is not allowed.
According to the documentation, 'RefererNotAllowedMapError' means
The current URL loading the Google Maps JavaScript API has not been
added to the list of allowed referrers. Please check the referrer
settings of your API key on the Google Developers Console.
I have the Google Maps Embed API set up for my own personal/work use and thus far have not specified any HTTP referrers. I register no errors. Your settings must be making Google think the URL you're visiting is not registered or allowed.
Just remind that if you just change it, it may take up to 5 minutes for settings to take effect.
I tried many referrer variations and waiting 5 minutes as well until I realized the example Google populates in the form field is flawed. They show:
*.example.com/*
However that only works if you have subdomain. or www. in front of your domain name. The following worked for me immediately (omitting the leading period from Google's example):
*example.com/*
According the google docs
this happened because the url on which you are using the Google Maps API, it not registered in list of allowed referrers
EDIT :
From Google Docs
All subdomains of a specified domain are also authorized.
If http://example.com is authorized, then http://www.example.com is also authorized. The reverse is not true: if http://www.example.com is authorized, http://example.com is not necessarily authorized
So,Please configure http://testdomain.com domain, then your http://www.testdomain.com will start work.
Check you have the correct APIS enabled as well.
I tried all of the above, asterisks, domain tlds, forward slashes, backslashes and everything, even in the end only entering one url as a last hope.
All of this did not work and finally I realised that Google also requires that you specify now which API's you want to use (see screenshot)
I did not have ones I needed enabled (for me that was Maps JavaScript API)
Once I enabled it, all worked fine using:
http://www.example.com/*
I hope that helps someone! :)
The Problem
Google suggests the format *.example.com/*This format does not work.
The Solution
Check the browser console for the Google Maps JavaScript API error: RefererNotAllowedMapError
Underneath the error it should have: "Your site URL to be authorized: https://example.com/".Use that url for the referrer and add a wildcard * to the end of it (https://example.com/*, in this case).
I found that even your HTTP Referreres are valid enough, wrong set of API Restrictions causes Google Maps JavaScript API error: RefererNotAllowedMapError.
For example:
You are using Javascript API for the key.
Add http://localhost/* to Application Restrictions / HTTP Referrences
Choose Maps Embed API instead of Maps Javascript API
This causes RefererNotAllowedMapError
There are lots of supposed solutions accross several years, and some don’t work any longer and some never did, thus my up-to-date take working per end of July 2018.
Setup:
Google Maps JavaScript API has to work properly with…
multiple domains calling the API: example.com and example.net
arbitrary subdomains: user22656.example.com, etc.
both secure and standard HTTP protocols: http://www.example.com/ and https://example.net/
indefinite path structure (i.e. a large number of different URL paths)
Solution:
Actually using the pattern from the placeholder: <https (or) http>://*.example.com/*.
Not omitting the protocol, but adding two entries per domain (one per protocol).
An additional entry for subdomains (with a *. leading the hostname).
I had the feeling that the RefererNotAllowedMapError error still appeared using the proper configuration (and having waited ample time). I deleted the credential key, repeated the request (now getting InvalidKeyMapError), created new credentials (using the exact same setup), and it worked ever since.
Adding mere protocol and domain seemed not to have included subdomains.
For one of the domains, the working configuration looks like this:
(As text:)
Accept requests from these HTTP referrers (web sites)
https://*.example.com/*
https://example.com/*
http://*.example.com/*
http://example.com/*
None of these fixes were working for me until I found out that RefererNotAllowedMapError can be caused by not having a billing account linked to the project. So make sure to activate your free trial or whatever.
This is another sh1tty Google product with a terrible implemenation.
The problem I have found with this is that if you restrict an API key by IP address, it wont work... BUT far be it from Google to make this point clear... It wasn't until troubleshooting and researching I found:
API keys with an IP addresses restriction can only be used with web
services that are intended for use from the server side (such as the
Geocoding API and other Web Service APIs). Most of these web services
have equivalent services within the Maps JavaScript API (for example,
see the Geocoding Service). To use the Maps JavaScript API client side
services, you will need to create a separate API key which can be
secured with an HTTP referrers restriction (see Restricting an API
key).
https://developers.google.com/maps/documentation/javascript/error-messages
FFS Google... Pretty important piece of information that would be good to clarify on setup...
Accept requests from these HTTP referrers (web sites)
Write localhost directory path
I experienced the same error:
This link talks about how to set up API key restrictions: https://cloud.google.com/docs/authentication/api-keys#adding_http_restrictions
In my case, the problem was that I was using this restriction:
HTTP referrers (web sites) Accept requests from these HTTP referrers
(web sites) (Optional) Use *'s for wildcards. If you leave this blank,
requests will be accepted from any referrer. Be sure to add referrers
before using this key in production.
https://*.example.net/*
This means that URLs such as https://www.example.net or https://m.example.net or https://www.example.net/San-salvador/ would work. However, URLs such as https://example.net or https://example.net or https://example.net/San-salvador/ would not work. I simply needed to add a second referrer:
https://example.net/*
That fixed the problem for me.
I add 2 website domains, set "*" in subdomain is not working but specific subdomain "WWW" and non-subdomain have been worked for my websites using the same Google Map API key.
dont' use "*" in subdomain
Hope it help.
That your billing is enabled
That your website has been added to Google Console
That your website is added to the referrers in your app.
(do a wildcard for both www and none www)
http://www.example.com/* and http://example.com/*
That Javascript Maps is enabled and you are using the correct credentials
That the website has been added to your DNS to enable your Google Console above.
Smile after it works!
Enable billing for Google project fixed the problem.
you show a screenshot of your api credentials page, but you have to click on "Browser key 1" and go from there to add referrers.
For deeper nested pages
If you have a project in a folder for example or nested pages
http://yourdomain.com/your-folder/your-page you can enter this in
http://yourdomain.com/*/*
The important part being /*/*/* depending how far you need to go
It seems that the * will not match / or get into deeper paths..
This will give your full domain access, well unless you have deeper nesting than that..
I struggled to make this work as well, but here are some pointers:
The URLs set as referrers include http, e.g. http://example.com/*
Google Maps JavaScript API was enabled
Billing was set-up on this account
Once all of this above was resolved, the maps displayed as expected.
http://www.example.com/* has worked for me after days and days of trying.
I got mine working finally by using this tip from Google:
(https://support.google.com/webmasters/answer/35179)
Here are our definitions of domain and site. These definitions are specific to Search Console verification:
http://example.com/ - A site (because it includes the http:// prefix)
example.com/ - A domain (because it doesn't include a protocol prefix)
puppies.example.com/ - A subdomain of example.com
http://example.com/petstore/ - A subdirectory of http://example.com site
I was attempting to use the Places API (Autocomplete) and had to also enable the Maps Javascript API from within Google Cloud Console before the Places API would work.
Removing the restrictions (to None) worked for me.
In my experience
http://www.example.com
worked fine
But, https required /* at the end
Chrome's Javascript console suggested I declare the entire page address in my HTTP referrer list, in this instance http://mywebsite.com/map.htm Even though the exact address is http://www.mywebsite.com/map.htm - I already had wildcard styles listed as suggested by others but this was the only way it would work for me.
This worked for me. There are 2 major categories of restrictions under api key settings:
Application restrictions
API restrictions
Application restrictions:
At the bottom in the Referrer section add your website url
" http://www.grupocamaleon.com/boceto/aerial-simple.html " .There are example rules on the right hand side of the section based on various requirements.
API restrictions:
Under API restrictions you have to explicitly select 'Maps Javascript API' from the dropdown list since our unique key will only be used for calling the Google maps API(probably) and save it as you can see in the below snap. I hope this works for you.....worked for me
Check your Script:
Also the issue may arise due to improper key feeding inside the script tag. It should be something like:
<script async defer src="https://maps.googleapis.com/maps/api/jskey=YOUR_API_KEY&callback=initMap"
type="text/javascript"></script>
If you are working on localhost then do not include http or https in the url.
Use "localhost" without protocols. I struggled for days and found it working.
Something no one else seems to have mentioned in here that may be important is also this:
Http referrers are case sensitive.
So say you have someone access https://www.example.com/webpage, and someone wrote a link to that page as https://www.example.com/Webpage, you need BOTH entries, otherwise one of them is not going to work (unless you URL-rewrite to remove caps, or replace /Webpage with /*, but in our case, we want to limit down to folders under a certain domain, so this is a pain in the butt).
I feel like this is a bit stupid. Yes, URLs can be case sensitive, but not to the point where you would restrict a folder if its in caps, but not if it's lowercase, right?

Getting geolocation from IP address

I need to track user details, for that client's location and IP address is needed.
I got IP address from
$this->input->ip_address();
in codiigniter. Now the problem is how can i make their location in google map by using their respective IP address
just use ipinfo.io at
http://ipinfo.io/
it uses a location api that we can post ip address and it will returns the location details as json:
we can able to display the loacation on map with the langitude and longitude details from json response to google Maps API.
Here is the code i used:
this script creates a Google Map instance with lattitude & longitude from json response:
jQuery(document).ready(function(){
jQuery.get("http://ipinfo.io/202.88.237.138", function (response)
{
var lats = response.loc.split(',')[0];
var lngs = response.loc.split(',')[1];
map = new GMaps({
el: '#map',
lat: lats, //latitude
lng: lngs //longitude
});
}, "jsonp");
});
and the map will displayed on:
<div style="border:1px solid red; height:745px;" id="map"></div>
Google Maps API gmaps.js is needed to run this..
As a viable (although often less accurate) alternative, the HTML5 spec includes Geolocation. As HTML 5 becomes more and more prevalent I think we can expect to see this become standard in the future. It also does not require the use of external web services or libraries. Everything you need to geolocate is built right into the clients browser.
I believe the primary method used is IP address as specified.
The Google Maps API will do the work of finding location using geoip for you. If the user is on a mobile device or has a more accurate way of locating themselves (like a GPS), it'll use that instead.
Here's a good starting point:
https://google-developers.appspot.com/maps/documentation/javascript/examples/map-geolocation
If you absolutely need to fetch location from IP only, there are third-party tools that you can scrape to get this information. You should make sure you have permission beforehand if you're using this in a larger project.
freegeoip.net provides a public HTTP API to search the geolocation of IP addresses. It uses a database of IP addresses that are associated to cities along with other relevant information like time zone, latitude and longitude.
You're allowed up to 15,000 queries per hour.
If you need more than that, you can run the freegeoip as a web server on your own infrastructure. See: freegeoip on github

Google geocoder returns wrong coordinates for address

I plot locations of real estate on a map. The address listed below is mapped incorrectly because it is a new build and I assume the street and everything is a new build, which is the reason Google can't find it in it's database.
What I want to happen is Google return "GeocoderStatus.ZERO_RESULTS" and not just pick a location with a related name and give me those coords.
The address I'm plotting is:
14018 Lonecreek Ave
Orlando, Florida 32828
If you submit the request via http, you get the same results i get through the API, see this link: http://maps.googleapis.com/maps/api/geocode/json?address=140
You'll see it comes back with "Lone Hill Drive" which is incorrect location. How can I tell Google return ZERO_RESULTS status in this instance?
Google's geocoding process isn't perfect (none are.)
What you can check for is the result's geometry.location_type property and test if it's value is "APPROXIMATE" to see if you can trust the returned lat/lng. Read more in the Documentation.
If it's way off you can report it directly to google.
You can use the API's Component Filtering to filter the results by a specific postcode. In such cases a non-exact match will have location_type of "APPROXIMATE" rather than the "GEOMETRIC_CENTER" you were seeing before.
http://maps.googleapis.com/maps/api/geocode/json?address=[address]&components=postal_code:[postcode]&sensor=false
Here's your geocoding request WITH component filtering
and WITHOUT component filtering

Categories