Determine if Google Maps API is using an invalid key during runtime - javascript

I'm looking for a way to determine whether a valid Google maps API key is being used. Using an invalid key, we receive an error stating that the google API has been disabled. I'd like to capture that return, and determine whether or not to do our geocoding functions based on that return.
As it stands, when we save a record, we look to see if the address has been changed. If it has, we get the geocode of that address, and after the success/failure message has been passed back, we continue on with our processing before we save the record.
When the API is disabled, the code simply stops. Nothing is returned - no success or failure. At this point, our code stops as well as we rely on the return so we know where to go from there. We are not looking for a way to get around licensing, simply a way to determine whether the API is disabled at runtime. Any ideas?

Well there's something i found in Web > Maps JavaScript API > Events under title "Listening for authentication errors"
If you want to programmatically detect an authentication failure (for
example to automatically send an beacon) you can prepare a callback
function. If the following global function is defined it will be
called when the authentication fails.
so you just need to define a global function:
function gm_authFailure() { /* Code */ };

Unfortunately there is no implemented option to detect a disabled API.
Last year I've made a feature-request , but I don't think that something will happen.
two possible options(there may be more):
when you use a map usually the API first will try to create the map(some elements will be added to the map-container ). When the API will be disabled, these elements will be removed. So you may do something when this happens(e.g. set a variable that indicates the disabled-status):
document.getElementById('map-canvas')//map-container
.addEventListener ('DOMNodeRemoved', function(e){
if(!this.children.length){
alert('the API has been disabled');
if(window.google && window.google.maps){
window.google.maps.disabled=true;
}
}
}, false);
override the alert-method to intercept the particular message:
(function(f){
window.alert=function(s){
if(s.indexOf('Google has disabled use of the Maps API for this application.')
===0){
if(window.google && window.google.maps){
window.google.maps.disabled=true;
alert('the API has been disabled');
return;
}
}
f(s);
}
})(window.alert)
In both cases you may later use the (custom)disabled-property of google.maps to check if the API has been disabled:
if(google.maps.disabled===true){
//execute alternative code
}

Related

Loqate Address Verifier - Detect Zero Credit OnLoad?

Using the Loqate Address Verification service, is there a way to programatically detect that your account is out of credit, on load of the control? Something like the code below (that I just made up)?
var controlToReturn = new pca.Address(fields, avOptions);
control.listen("load", function () {
if (this.accountCredit == 0) {
//do stuff
}
});
It's possible to handle a zero credit error thrown by the control after you've used it, but at that point you've displayed an address search field, and then have to hide it, and fall back to a standard address form layout (in our case at least).
controlToReturn.listen("error", function (message) {
console.error(message);
const ERROR_MESSAGE_ZERO_CREDIT = "Account out of credit";
if (message != ERROR_MESSAGE_ZERO_CREDIT)
alert("Error with address checker service: " + message);
}
There doesn't seem to be anything in their docs, but I just wondered if anyone knew of any properties on the control / other API calls that would allow this?
The problem is that the Loqate address.js library, which calls their API, is not returning the whole error object, just the message.
This may not be an approach that is endorsed by Loqate, but you can access the original error object through the reference to the pca.Address in the 'error' listener.
You should be able to do this (in the 'error' listener function):
var errorCode = this.error.arguments[1].response.Items[0].Error;
'arguments[1]' is the pca.Request object that caused the error, and 'Items[0]' is the error object, which has the properties 'Error' (the code), 'Description', 'Cause' and 'Resolution'.
Note that 'errorCode' is a string at this point, so you might also want to use parseInt on it.
The full list of error codes is available on the Loqate website. 'Account out of credit' is '3', but there are a number of other errors that you may want to handle differently.

Strange error message being returned when creating calendar event

I'm creating a google calendar event using the Node.js Google Client API, I'm requesting a conference be created with the event using the following object:
var conferenceData =
{
createRequest:
{
requestId: uuid(),
conferenceSolutionKey:
{
type: "hangoutsMeet"
}
}
}
I get an error back from the server saying: Error: Invalid conference type value. Which doesn't make any sense, since, according to this documentation hangoutsMeet is an acceptable value:
The possible values are:
"eventHangout" for Hangouts for consumers (http://hangouts.google.com)
"eventNamedHangout" for classic Hangouts for G Suite users (http://hangouts.google.com)
"hangoutsMeet" for Hangouts Meet (http://meet.google.com)
Anybody have any idea why it could be returning that error?
I am facing the same problem at the moment.
I believe it actually comes from the fact that the calendar where you try to insert the event does not accept the "hangoutsMeet" conference call type.
You can check that by using the API to get the calendar setup details, in conferenceProperties.allowedConferenceSolutionTypes:
- https://developers.google.com/calendar/v3/reference/calendars/get
- https://developers.google.com/calendar/v3/reference/calendars#resource
For my particular case, I can observe that the calendar only supports "eventNamedHangout", and "hangoutsMeet" is not listed.
That being said, I have no idea about how to actually make sure the "hangoutsMeet" type is supported by a specific calendar resource.
Edit
It seems that my problem was coming from the fact I was using a GCP service account - in that case what I observe is that only the eventNamedHangout type is supported.
When sending the very same payload to the API with an access_token obtained via the oauth dance, hangoutsMeet becomes available.
I got this working. As per the events docs you referred to, if providing conferenceSolution then at least one entryPoint must also be provided. Otherwise use createRequest:
"Either conferenceSolution and at least one entryPoint, or createRequest is required."
Does your uuid() return a string ?
and try smth like this instead :
const event = {
"conferenceData": {
"createRequest": {
"requestId": "someRandomKey",
"conferenceSolutionKey": {
"type": "hangoutsMeet"
}
}
}
};

Google Tag Manager Virtual Page View

I have a little problem setting up a virtualPageView which should override the URL which is sent to google when no result is present.
Heres what I have as JavaScript code:
function returnNoSearchResultsGoogleTagManagerCode($searchterm){
if ($searchterm == "") return "";
$requestUri = $_SERVER['REQUEST_URI'] . "&no_result=".$searchterm;
$js = "<script>
$(document).ready(function(){
dataLayer.push({
'event':'empty_result',
'virtualPageURL':'".$requestUri."'
});
});
</script>";
return $js;
}
As you can see, I want to use an event trigger (empty_result).
In google, I use a Trigger to determine if the Page is a no result Page. First i created a custom Variable with custom JS
function(){
if (document.getElementsByClassName('ga-no-result').length > 0){
return true;
}else{
return false
}
}
The class is set, if the SearchEngine can't find a result. So far so good.
I also created a dataLayer variable to hold the virtualPageURL
Now I need an event which is triggered if the variable is true.
Finally I created a Tag with type PageView which is fired when the event occurs:
Until now it seems okay, the Tag is properly configured (i guess) but if I do a search which has no result, the Page URL is not overridden
The Tag is properly fired and the variables are filled. The overview of the dataLayer shows a correct dataLayer event.
But the PageURL is not overridden... Even if I wait a whole day, the category isn't sent to google.
What am I doing wrong?
I would be very thankful if someone would have an idea or even a solution :)
Thanks in advance
exa.byte
UPDATE:
Hey, I forgot to mention, that I want to use the new page variable as the string which google should use to determine the searchterm and the searchcategory
In Google Analytics I configuered the search as the "q" parameter and the "no_result" as the category.
Is it even possible to change the string which google will parse in the end?
To send a virtual pageview to Google Analytics, the field you need to change is page not {{Page Url}} , also the title field is often used.
That's really the only two things you need to do to send a simple virtual pageview.
Extra: I always start my pagepath with /virtual/ to be able to recognize which ones are virtual pageviews easily in GA
For virtual page view you have to change Field "page" - in your GTM-OnSearchEmptyResult you are changing "{{Page URL}}" - I don't think that's correct way to send virutal pageview. Also if you need to change hostname use Fieldname "hostname".
In preview mode you will not see Page URL changed in Variables Tab, you have to go to the actual GA tag that is fired and check it's values. You can either do this in GTM's preview tool or you can use standard developer tools - Network Tab and see what values are being sent to GA:
You can see "dl" parameter is the current page, if you set up virtual page you should also see parameter called "dp" this is going to be the new value of page in your GA.
If you want to setup virtual pageview you have to use page instead of {{Page URL}} in your fieldname and for Document title use title in you fieldname.
for more field reference of google analytics follow below link
https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#hitType.
If you don't want to mess around with custom Tag Manager events it's still possible to use the good old ga method, even if you don't include the Analytics code on the page. You just need to fetch the right tracker dynamically, as explained by Simo Ahava in this thread.
if (typeof ga === "function") {
ga.getAll().forEach((tracker) => {
tracker.set('page', '/my/path'); // <- change here
tracker.send('pageview');
});
}
I also put it in a gist here.
thanks for your help. I think I got rid of the Problem and have solved it now. I will describe my solution below:
The solution is quite simple.
I had an error/ spelling error # google backend. I set the search_category parameter to "no_results", but used "no_result" for implementation...
Pretty dumb, but sometimes you just won't see the wood for the trees...
I created a new Trigger as helper "HelperDomReady" to trigger the only if DOM is ready and the variable "isEmptySearch" equals "(bool)true"
Now I can see the searchterms which have no result in google backend in the "sitesearch categories" summary. Since I won't set the parameter at all, if the search had at least one hit, the site-search category shows "not-set" for successful results. Therfore the category-section will only show searches without a hit. Problem solved :)
Disadvantage: The searchterm is also listed in the normal list. But I think this is negligible

Google Tag Manager - read cookie just after they are set

I need to read cookie that are set by Google Tag Manager.
Right now if Google Tag Manager is loaded first time for end-user I can't read cookies (because it happens later, but not immediately).
Is there a good way (callback?) that can help me to read cookies once they are set? This issue is only relevant if user visits page first time.
From the discussion in the comments below the question, I would suggest the following solution (assuming you also send Pageviews to Google Analytics). Examples are based on Simo Ahava's (excellent) blog.
(Please note that I haven't had the opportunity to test it thoroughly, as I am currently unable to create a complete test case for this setup -- there might be some hiccups)
1. Create a Variable to read the _ga cookie
Reference: https://www.simoahava.com/analytics/macro-magic-google-tag-manager/#1-client-time
This will return the value for the cookie with name specified (be careful in where you use the value read, as there is always a chance that cookies are rejected by the User's browser policies).
Create a new Variable, with:
Variable Name of GA Cookie
Cookie Name of _ga
(source: simoahava.com)
2. Define a callBackFunction
Reference: https://www.simoahava.com/analytics/macro-magic-google-tag-manager/#8-hitcallback-with-a-universal-analytics-tag & https://www.simoahava.com/analytics/macro-magic-google-tag-manager/#6-get-clientid-using-_ga-cookie
This callback function will be executed right after the Pageview is sent (i.e. after the _ga cookie is set).
Create a Custom JavaScript Macro with the following code:
function () {
return function () {
// Code to be executed in order to read the cookie:
try {
var gaCookie = {{GA Cookie}};
// Do what you need to with the cookie here:
// ...
return gaCookie;
} catch (e) {
console.log('No Universal Analytics cookie found.');
return 'N/A';
}
}
}
3. Define a hitCallback after sending the Pageview
Reference: https://www.simoahava.com/analytics/macro-magic-google-tag-manager/#8-hitcallback-with-a-universal-analytics-tag
This will execute the callback function you just defined right after the Pageview is sent.
In the Fields to set option of your Pageview Tag, set:
Field Name to hitCallback
Value to {{callBackFunction}}
Hope it can help you move forward.

How do I catch an invalid API key for google maps

I have this code:
<script src="http://maps.google.com/maps?file=api&v=2&sensor=false&key=babab" type='text/javascript'></script>
If the key is invalid then it pops up an alert, but I want to perform some action in this case. I'm not sure how to hook into it though. Any ideas?
Google does not offer an external method of checking the Google Maps API key. Hence you cannot query some service with e.g. "Is this code valid abcde1234" and get a TRUE/FALSE response.
There is a discussion on how the Maps API key is generated. But I suggest you look at a post from Mike Williams about the GValidateKey function. This is the function actually doing the magic validation - what it exactly does, like creating a hash from your Google account / domain - we don't know.
I see two solutions for your problem of checking whether the API key provided is correct:
Overwrite the incoming alert with some custom code (check for the content of the alert, or check if an alert occurs withing X seconds after page load)
Somehow get the GValidateKey function to validate your key beforehand. Maybe you can call it before referencing the API Javascript? Sounds kind of hackish to me...
The problem you will likely have is that you don't know what Google actually checks. The referrer, the referring site, the host - many possibilities (it is not the IP address of the server, but the name plus some additional information).
I just ran across the need to perform an action if an invalid API key was used. Google's documentation states:
If you want to programmatically detect an authentication failure (for example to automatically send an beacon) you can prepare a callback function. If the following global function is defined it will be called when the authentication fails.
This was all I needed to do:
function gm_authFailure() { // Perform action(s) }
For modern browsers (IE9+ and others) you may use DOMNodeRemoved event. You just need to add event handler to the element that you pass to the map constructor:
var map = new google.maps.Map(element, myOptions);
element.addEventListener("DOMNodeRemoved", function(e){
if (e.target === element){
//your code here
element.removeEventListener("DOMNodeRemoved", mapWasRemovedHandler, true);
}
}, false);

Categories

Resources