Google Earth Engine Client Javascript API authentication is not working - javascript

I have read the Google Earth Engine Client side Javascript API documentation. Here is the minimal code to start using Google Earth Engine Google Earth Engine Try it yourself
I have signed up for the Google Earth Engine here using my Google Account.
I have also followed all the prerequisites step for creating Project, Enabling Google Earth Engin API, Creating oAuth Client ID and Setting up everything.
The issue that I am facing here is that the code is not working as expected, when I went to the console and saw network tab, I realized there is a request of checkOrigin which always return
{
blocked:true
suppressed:false
valid:true
}
Same as in this question. While I have added the origin in Authorised JavaScript origins while creating API for Web Application.
NOTE: I am using wampserver and I have also added tested emails to the project.
Here is my current code:
<!DOCTYPE html>
<html>
<head>
<meta name="referrer" content="no-referrer-when-downgrade" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=myworkingGoolgeMapKey&callback=doNothing"></script>
<script src="https://ajax.googleapis.com/ajax/libs/earthengine/0.1.336/earthengine-api.min.js"></script>
<style>
/* Set the size of the div element that contains the map. */
#map-container {
height: 400px;
width: 100%;
background-color: #eee;
}
</style>
</head>
<body>
<!-- The "Sign in with Google" button, initially hidden. -->
<input
id="g-sign-in"
type="image"
src="https://developers.google.com/identity/images/btn_google_signin_light_normal_web.png"
onclick="onSignInButtonClick()"
alt="Sign in with Google"
hidden
/>
<!-- Element where map will be added. -->
<div id="map-container"></div>
<script>
function doNothing(){
console.log("ok");
}
function errorInit(){
console.log("initialize error");
}
// The OAuth Client ID from the Google Developers Console.
const CLIENT_ID = "myclientidFromoAuth.apps.googleusercontent.com";
// Initializes Maps JavaScript API and Earth Engine API, instructing the map
// to pull tiles from Earth Engine and to overlay them on the map.
function setUpMap() {
// Hide the sign-in button.
document.getElementById("g-sign-in").setAttribute("hidden", "true");
// Initialize the Earth Engine API. Must be called once before using the API.
ee.initialize();
// Get a reference to the placeholder DOM element to contain the map.
const mapContainerEl = document.getElementById("map-container");
// Create an interactive map inside the placeholder DOM element.
const embeddedMap = new google.maps.Map(mapContainerEl, {
// Pan and zoom initial map viewport to Grand Canyon.
center: {lng: -112.8598, lat: 36.2841},
zoom: 9,
});
// Obtain reference to digital elevation model and apply algorithm to
// calculate slope.
const srtm = ee.Image("CGIAR/SRTM90_V4");
const slope = ee.Terrain.slope(srtm);
// Create a new tile source to fetch visible tiles on demand and display them
// on the map.
const mapId = slope.getMap({min: 0, max: 60});
const tileSource = new ee.layers.EarthEngineTileSource(mapId);
const overlay = new ee.layers.ImageOverlay(tileSource);
embeddedMap.overlayMapTypes.push(overlay);
}
// Handles clicks on the sign-in button.
function onSignInButtonClick() {
// Display popup allowing the user to sign in with their Google account and to
// grant appropriate permissions to the app.
ee.data.authenticateViaPopup(setUpMap);
}
// If the user is signed in, display a popup requesting permissions needed to
// If the user is signed in, display a popup requesting permissions needed to
// run the app, otherwise show the sign-in button.
$(document).ready(function(){
ee.data.authenticateViaOauth(
// The OAuth Client ID defined above.
CLIENT_ID,
// Callback invoked immediately when user is already signed in.
setUpMap,
// Show authentication errors in a popup.
errorInit,
// Request permission to only read and compute Earth Engine data on behalf of
// user.
/* extraScopes = */ ['https://www.googleapis.com/auth/earthengine'],
// Show sign-in button if reusing existing credentials fails.
() => document.getElementById("g-sign-in").removeAttribute("hidden"),
// Don't require ability to write and access Cloud Platform on behalf of the
// user.
/* opt_suppressDefaultScopes = */ true
);
});
</script>
</body>
</html>

Related

Implementing Google Analytics Script AFTER the Visitor Accept Using Body of Page

The aim is simple, run the google tracking code AFTER the user has accepted and if the user do not accept, do not run.
I went with placing the code inside the tag, but I am struggling to understand how to incorporate a "dismiss" option as well.
This is my "work in progress" code as of right now:
<script>
(function() {
if (!localStorage.getItem('cookieconsent')) {
document.body.innerHTML += '\
<div class="cookieconsent" style="position:fixed;padding:20px;left:0;bottom:0;background-color:#000;color:#FFF;text-align:center;width:100%;z-index:99999;">\
This site uses standard cookies and Google Analytics. By clicking on "I understand", you agree to their use. \
I Understand\
</div>\
';
document.querySelector('.cookieconsent a').onclick = function(e) {
e.preventDefault();
document.querySelector('.cookieconsent').style.display = 'none';
localStorage.setItem('cookieconsent', true);
};
}
})();
</script>
And from what I understand, I need to place the google tracking after this line:
localStorage.setItem('cookieconsent', true);
But since the script tag is already opened, how do I do that?
Example of the tracking code:
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXX');
</script>
On top of this, I'm not sure how to add a dismiss option so that the google code does not run. I'm grateful for all the input I can get.
This probably contains the answer to your question Consent Mode (beta):
"Consent Mode (beta) allows you to adjust how your Google tags behave based on the consent status of your users. You can indicate whether consent has been granted for Analytics and Ads cookies. Google's tags will dynamically adapt, only utilizing measurement tools for the specified purposes when consent has been given by the user."

How to track google maps interactions with Google Tag Manager

I am trying to get users interactions in google map (zoom in/out, map changed) that is embedded with iframe in my website. I read lots of articles for submiting Forms, but with iframe maps, could not find a way. Which is the right trigger, in order to accoplish that?
For now, I have created a custom HTML tag that has this kind of code:
<script>
try {
var postObject = JSON.stringify({
event: 'mapChanged',
});
parent.postMessage(postObject, 'https://www.example.com/contact/');
} catch(e) {
window.console && window.console.log(e);
}
</script>
and a trigger that has this options:
Page View and Page URL equals to: https://www.example.com/contact/
Because of the trigger I could see the tag in GTM, but of course this is not correct.. I do not want to trigger every time a user visit the contact page, but when clicks on the map or zoom in/out

How to expand Watson Assistant on Page Load

I would like to ask if it is possible to expand a Watson Assistant Chatbot on page load ? Currently, when the page loads, a user will then have to click on the little icon below to start the chatbot.
Watson Assistant Chatbot Icon
I am using Chrome, and the solution should also be working on mobile platforms.
I have the following empty page with the chatbot script so far :
<body style="height: 100%;">
<script src=https://assistant-web.watsonplatform.net/loadWatsonAssistantChat.js></script>
<script>
window.loadWatsonAssistantChat({
integrationID: "some id", // The ID of this integration.
region: "eu-gb" // The region your integration is hosted in.
}).then(function(instance){
instance.render();
});
</script>
</body>
</html>
Looking above I notice that you are using the new IBM Web Chat client, which is added to your html page. If you notice in the documentation for the web client - there is the section about extending the web chat and the extra documentation in GitHub.
In that documentation you will find a list of extra options that can be added to the creation of your instance of Web Chat. One of those options is to have the Web Chat open on loading the web page, rather than the icon. Or even adding the web chat to your own icon.
The option you are after is;
options.openChatByDefault - boolean - Optional - false - Whether to render the chat window initially in an open state. By default, the chat window is rendered in a closed state.
So your code should be;
<body style="height: 100%;">
<script src=https://assistant-web.watsonplatform.net/loadWatsonAssistantChat.js></script>
<script>
window.loadWatsonAssistantChat({
integrationID: "some id", // The ID of this integration.
region: "eu-gb", // The region your integration is hosted in.
options.openChatByDefault: true
}).then(function(instance){
instance.render();
});
</script>
</body>
</html>
Acording to the API you need openChatByDefault: true within window.watsonAssistantChatOptions = {...}.
Mind that my version of the API at the time of answering is different than that of the question, it goes with the following script for the embed.
window.watsonAssistantChatOptions = {
integrationID: "############", // The ID of this integration.
region: "eu-gb", // The region your integration is hosted in.
serviceInstanceID: "############", // The ID of your service instance.
onLoad: function(instance) { instance.render(); },
openChatByDefault: true
};
setTimeout(function(){
const t=document.createElement('script');
t.src="https://web-chat.global.assistant.watson.appdomain.cloud/versions/" + (window.watsonAssistantChatOptions.clientVersion || 'latest') + "/WatsonAssistantChatEntry.js"
document.head.appendChild(t);
});

What is the best way to develop shopping offers chrome extension?

I have a requirement of developing chrome extension which will display latest offers and coupons if I visit any affiliate store like amazon, aliexpress, flipkart, myntra etc.
When I visit their website and if my extension is installed then that website will should be injected with popup having offers and coupons of that website. (I have a webservice from where i will fetch offers and coupons).
It will be something like shown in below image.
I have tried something similar this way but i'm not sure it's the right way to do.
From Manifest.json
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["jquery.js","myscript.js"],
"css":["offers.css"]
}
],
"web_accessible_resources":[
"offers.html",
"offers.js"
]
myscript.js
var url = chrome.extension.getURL('offers.html');
var iframe = "<iframe src='"+url+"' id='IframeID'></iframe>";
var host = window.location.host;
var splittedHost = host.split('.');
var title = $(document).find("title").text();
if(title != ''){
$('body').append(iframe);
}
offers.html
<html>
<head>
<meta charset="UTF-8">
<title>test| Latest Offers</title>
<script src="jquery.js"></script>
<script src="offers.js"></script>
</head>
<body id="bodyText">
<h1>
Welcome
</h1>
...
</body>
</html>
Using This I got something like this in every page I visit:
That iframe is actually offers page and to get offers data I need host name from url. I tried getting window.localtion.host in offers.js injected in offers.html but I get chrome://extension.
Can anyone suggest me how to get host name in offers.js or is there any way I can append data in offers.html from myscripts.js? and where to call the API and how to append result in to iframe body?
Can anyone suggest me how to get host name in offers.js or is there any way I can append data in offers.html from myscripts.js?
As a quick solution, if you only need the URL, you can pass it as a query parameter:
// myscript.js
var url = chrome.extension.getURL('offers.html?url=' + window.location.host);
// offers.js
// Using https://developer.mozilla.org/en-US/docs/Web/API/URL
var host = new URL(location.href).searchParams.get('url');
If you do need to extract more information from the page, you can use postMessage for communication with the embedded window.
// myscript.js
iframe.contentWindow.postMessage(message, chrome.runtime.getURL(""));
// offers.js
window.addEventListener("message", function(event) {
var message = event.data;
/* ... */
});
This can be made bi-directional as well, though this is outside the question's scope.
where to call the API and how to append result in to iframe body?
Well, in offers.js, and then modify the DOM of that page.
Edit: Apparently, this is problematic as security policies from the page leak into the iframe, blocking a call to HTTP endpoint.
You should use HTTPS to begin with. It's the privacy of your users that is at stake.
You can work around it by delegating the API call to a background page using Messaging. A background page does not have this restriction.
..you still should be using HTTPS. This can be a reason for rejection when your extension is reviewed.

Geolocation not working with apple-mobile-web-app-capable?

I have the following JS to display the current user's Zipcode in #zip:
(function ($, geolocation) {
if (geolocation) {
geolocation.getCurrentPosition(function (position) {
$.getJSON(
"http://ws.geonames.org/findNearestAddressJSON?callback=?",
{
lat : position.coords.latitude,
lng : position.coords.longitude
},
function (data) {
$(function () {
$('#zip').text(data.address.postalcode);
});
}
);
});
}
}(jQuery, navigator.geolocation));
I also have a JS function to reload the page:
$('.reload').click(function(){
window.location.reload(true);
});
In Mobile Safari, these two functions work together well. If the user opens the webpage, it will load the user's current zipcode. Then, if the user changes locations, the user can reload the page by tapping the botton. This works fine, except when <meta name="apple-mobile-web-app-capable" content="yes"> is present.
When it is present, this what happens:
User taps the icon on their home screen
Webpage opens, with the address bar hidden, as <meta name="apple-mobile-web-app-capable" content="yes"> does this
Zipcode loads like it should
User moves location, taps the reload button
Page fails to show the zipcode, with no erros logged to the console
I'm really stuck on how to fix this, but if this helps at all, here's a working example:
http://www.codekraken.com/testing/zipper/zip.html
There is no reload in full-screen web apps (using apple-mobile-web-app-capable). However, when the user changes location, and then runs the app again, it will always load the page. It won't fire the reload event, but it will fire the onload event - every time it runs.
If the user leaves the app running and changes location, you'll need a simple "find me again" function that simply reruns your code to find the current location and zipcode.
Now - HERE is a catch! I've found that on iOS, the position is often cached, even if you tell it to only use a fresh location, so sometimes, you'll get the old location. I created a workaround for this called getAccurateCurrentLocation() that uses a very similar interface. You can find the code at https://github.com/gwilson/getAccurateCurrentPosition - it's very simple to drop in as a replacement to getCurrentPosition().
That should do it.
In case anyone else has confusion (as I had), the method involved here is the native "watchPosition" method of the geolocation object.
WatchPosition MDN Specs
The watchPosition method will be called when the user moves location, and you can specify your lat/long to zip generator as the callback.
From the specs:
var watchID = navigator.geolocation.watchPosition(function(position) {
do_something(position.coords.latitude, position.coords.longitude);
});
so it looks like you could do:
var watchID = navigator.geolocation.watchPosition(function(position) {
$.getJSON(
"http://ws.geonames.org/findNearestAddressJSON?callback=?",
{
lat : position.coords.latitude,
lng : position.coords.longitude
},
function (data) {
$(function () {
$('#zip').text(data.address.postalcode);
});
}
);
});
which will accomplish even more simplicity -- the user will not have to tap the location button, it should already be updated as they move.
To be clear, Greg's function uses this watchPosition method, but if you want to understand what is at work, or use the much leaner native code and customize it yourself, watchPosition is your tool.
Fullscreen mode launches the browser in a WebSheet which might have a separate set of geolocation permissions. Maybe previously you declined to share the geolocation information in a WebSheet but allowed it in the Safari browser.
And if I recall correctly, WebSheets are known to reset their permissions from time to time and prompt the user again to allow reading geolocations every few hours.

Categories