I am trying to make a functional connection to GA API according to the official docs - https://developers.google.com/analytics/devguides/reporting/core/v4/quickstart/web-js. I did everything needed to set it up however the solution is not working. The weird thing is that the button for the authentication is loaded and its working up until the point where I select the google account to login with. After that however loading appears and the auth window gets closed. There is no error in the console, nothing happens at all.
I use it on localhost currently but I've also tried it on a server with the same result. After selecting the account, every next attempt doesn't even require choosing the account so the window just opens, loading appears and closes again without anything happening.
screenshot
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello Analytics Reporting API V4</title>
<meta name="google-signin-client_id" content="<CLIENT-ID>">
<meta name="google-signin-scope" content="https://www.googleapis.com/auth/analytics.readonly">
</head>
<body>
<h1>Hello Analytics Reporting API V4</h1>
<!-- The API response will be printed here. -->
<textarea cols="80" rows="20" id="query-output"></textarea>
<!-- The Sign-in button. This will run `queryReports()` on success. -->
<p class="g-signin2" data-onsuccess="queryReports"></p>
<script>
const VIEW_ID = '<VIEW-ID>';
// Query the API and print the results to the page.
function queryReports() {
gapi.client.request({
path: '/v4/reports:batchGet',
root: 'https://analyticsreporting.googleapis.com/',
method: 'POST',
body: {
reportRequests: [
{
viewId: VIEW_ID,
dateRanges: [
{
startDate: '7daysAgo',
endDate: 'today'
}
],
metrics: [
{
expression: 'ga:sessions'
}
]
}
]
}
}).then(displayResults, console.error.bind(console));
}
function displayResults(response) {
var formattedJson = JSON.stringify(response.result, null, 2);
document.getElementById('query-output').value = formattedJson;
}
</script>
<!-- Load the JavaScript API client and Sign-in library. -->
<script src="https://apis.google.com/js/client:platform.js"></script>
</body>
</html>
Is there something wrong in the code which I missed?
Related
When creating notifications with the notification API the notifications are not displaying.
I was recently trying to use the notification api in order to create a simple notification and display it. Eventually I was going to use notifications In an app that I am building. The requesting permission step went smoothly but when I created the notification It simply did not display.
I know that my browser supports the notification api and I do not have them blocked. I am also not using a mobile device and I am using the latest version of chrome. These notification are not displaying anywhere, including websites with ssh encryption.
Here is my code:
async function notify(data) {
function createNotification(data) {
const notification = new Notification(data.title, {
icon: data.icon,
body: data.body
})
return notification
}
function checkNotifications() {
if(Notification) {
return true
} else {
alert('Notifications are not supported on this browser.')
return false
}
}
if(checkNotifications()) {
if(Notification.permission === 'granted') {
createNotification(data)
} else {
if(await Notification.requestPermission() === 'granted') {
console.log(createNotification(data))
} else {
alert('you will not recive notifications')
}
}
}
}
notify({title: 'test', body: '<b>hello</b>', icon: '../logo.png'})
Here is my html:
<!DOCTYPE html>
<html>
<head>
<title>website</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<script type='text/javascript' src='./notification.js'></script>
</body>
</html>
Expected results:
The notification displays
actual results:
No error, but no notification either.
EDIT:
The notifications work If I set the notification to 'allow' instead of 'ask'.
Do you have this in manifest?
"permissions": [
"contentSettings"
],
And then in your script...
chrome.contentSettings.notifications.set({primaryPattern:'<all_urls>',setting:'allow'});
Sorry, are you server side or client?
https://developer.chrome.com/extensions/contentSettings
Check your windows settings has notifications enabled.
https://support.microsoft.com/en-us/windows/change-notification-settings-in-windows-10-ddcbbcd4-0a02-f6e4-fe14-6766d850f294
https://support.microsoft.com/en-us/windows/change-notification-and-action-settings-in-windows-10-8942c744-6198-fe56-4639-34320cf9444e
Start > Settings > System > Notifications and actions
You can also click on the notification hub on the bottom right of your screen and then click on manage notifications. You may have them enabled, but you could also be blocking chrome based ones.
I am trying to follow the simplest of examples of how to setup up Google's "
One tap sign-up and automatic sign-in" in a web page. Just copy and pasting the code provided by google, I get an exception "No credentials available". Why? How to fix it?
This is my web page content ...
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title of the document</title>
<link rel="icon" href="favicon.ico" type="image/x-icon" />
<script src="https://smartlock.google.com/client"></script>
<script>
console.log( "window.location.origin=" + window.location.origin);
window.onGoogleYoloLoad = (googleyolo) => {
console.log("Google one tap ready");
};
const retrievePromise = googleyolo.retrieve({
supportedAuthMethods: [
"https://accounts.google.com",
"googleyolo://id-and-password"
],
supportedIdTokenProviders: [
{
uri: "https://accounts.google.com",
clientId: "xxxx-86peetl434op89ug41lg1vv8sjspfupp.apps.googleusercontent.com"
}
]
});
</script>
</head>
<body>
Content of the document......
</body>
</html>
The Authorized JavaScript origins has been correctly setup. I am confident of that. The URL for the above content is: https://s3-ap-southeast-2.amazonaws.com/sbd-aws-sdk-delphi-22/index.html
Upon hitting the page (browser=Chrome), the resultant javascript console is ..
window.location.origin=https://s3-ap-southeast-2.amazonaws.com
Google one tap ready
index.html:1 Uncaught (in promise)
a {type: "noCredentialsAvailable", name: "OpenYoloError", message:
"noCredentialsAvailable: No credential is available for the current user."}
message:
"noCredentialsAvailable: No credential is available for the current user."
Context: When I make this web page hit, I am logged into Google.
What am I doing wrong?
The problem is that there is currently no user signed in. The library has very little support for this, as a work around, when no Google Accounts are active and no credentials are available. You can simply show the traditional Google Sign-In button and have the user click to proceed through the flow to activate their Google Account in the browser.
https://developers.google.com/identity/sign-in/web/
I am trying to implement a Google Play leaderboard in a very basic javascript game:
I have included what I think are the necessary meta tags, signon, and scripts in my index.html file:
<meta name="google-signin-client_id" content="xxxxxxxxxxxx-xxxxxxxxxxx.apps.googleusercontent.com" />
<meta name="google-signin-cookiepolicy" content="single_host_origin" />
<meta name="google-signin-callback" content="signinCallback" />
<meta name="google-signin-scope" content="https://www.googleapis.com/auth/games" />
I've included a standard google sign on button:
<div class="g-signin2" data-onsuccess="onSignIn"></div>
I've included the google apis:
<script src="https://apis.google.com/js/client.js"></script>
<script src="https://apis.google.com/js/platform.js" async defer></script>
In my games.js file, I've included the call to submit the scores by:
gapi.client.load('games','v1',function(response) {
var request2 = gapi.client.games.scores.submit(
{leaderboardId: "xxxxxxxxxx",
score: 50}
);
request2.execute(function(response) {
console.log(response);
// blah blah blah
});
But nothing ever shows up on the leaderboard. The console log spit out what I'm expecting. I've confirmed the clientID and leaderboardID.
For some reason the scores aren't actually being submitted (or if they are, they aren't being processed). Anyone with experience setting this up available for some pointerd? Note that this is not a chrome app/extension - it's a pure javascript game hosted on a web server.
Based on the Leaderboards for the Web, Scores.submit by using the URI request:
POST https://www.googleapis.com/games/v1/leaderboards/leaderboardId/scores
I did not see this part on your code.
Check this firewall-defense playgames sample for more code implementation.
So I'm trying to build a mobile app using Durandal. However, I am having trouble to do so with Google plus JS API integration. I think here is the problem: The javascript client for gapi comes with asynchronous loading, so durandal initialization will crash having gapi undefined and because of this, the css components also do not render properly also. I have tried putting the following script tags in the login.html file of my view for login.js or even in the require.js section of my main.js but it's still not working. Scripts for linking to Google Api:
<script src="https://apis.google.com/js/client:platform.js" async defer> </script>
<script src="https://apis.google.com/js/platform.js?onload=onLoadCallback" async defer></script>
//onSignInCallBack function to call in login.js after user signs in vis Google Plus
onSignInCallback: function(authResult) {
gapi.client.load('plus','v1').then(function() {
if (authResult['access_token']) {
$('#authOps').show('slow');
$('#gConnect').hide();
var user_access_token = authResult['access_token'];
var id_token = authResult['id_token'];
} else if (authResult['error']) {
// There was an error, which means the user is not signed in.
console.log('There was an error: ' + authResult['error']);
$('#authOps').hide('slow');
$('#gConnect').show();
}
console.log('authResult', authResult);
});
},
Here is my main.js file:
requirejs.config({
paths: {
'text': '../Scripts/text',
'durandal': '../Scripts/durandal',
'plugins': '../Scripts/durandal/plugins',
'transitions': '../Scripts/durandal/transitions',
'knockout' : '../Scripts/knockout-3.1.0',
'bootstrap': '../Scripts/bootstrap',
'jquery':'../Scripts/jquery-1.9.1',
'async':'../Scripts/async'
}
});
define(['durandal/system',
'durandal/app',
'durandal/viewLocator',
'durandal/binder',
'utils/routines',
'async!https://apis.google.com/js/platform.js?onload=onLoadCallback',
'async!https://apis.google.com/js/client:platform.js'
], function (system, app, viewLocator, binder,routines,callback,gapi) {
//>>excludeStart("build", true);
system.debug(true);
//>>excludeEnd("build");
app.configurePlugins({
router: true,
dialog: true,
widget: true
});
app.start().then(function() {
//Replace 'viewmodels' in the moduleId with 'views' to locate the view.
//Look for partial views in a 'views' folder in the root.
viewLocator.useConvention();
//Show the app by setting the root view model for our application with a transition.
app.setRoot('shell/shell', 'entrance');
// override bad route behavior to write to
// console log and show error toast
/*
router.handleInvalidRoute = function (route, params) {
logger.logError('No route found', route, 'main', true);
};
*/
});
});
Here is my index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="format-detection" content="telephone=no" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="apple-touch-startup-image" href="/Content/images/ios-startup-image- landscape.png" media="(orientation:landscape)" />
<link rel="apple-touch-startup-image" href="/Content/images/ios-startup-image-portrait.png" media="(orientation:portrait)" />
<link rel="apple-touch-icon" href="~/Content/images/icon.png" />
<link href="/Content/ie10mobile.css" rel="stylesheet" />
<link href="/Content/bootstrap.min.css" rel="stylesheet" />
<link href="/Content/font-awesome.min.css" rel="stylesheet" />
<link href="/Content/durandal.css" rel="stylesheet" />
<link href="/Content/starterkit.css" rel="stylesheet" />
<script type="text/javascript">
if (navigator.userAgent.match(/IEMobile\/10\.0/)) {
var msViewportStyle = document.createElement("style");
var mq = "##-ms-viewport{width:auto!important}";
msViewportStyle.appendChild(document.createTextNode(mq));
document.getElementsByTagName("head")[0].appendChild(msViewportStyle);
}
</script>
</head>
<body>
<div id="applicationHost">
<div class="text-center">
<br/><br/><br/><br/>
<i class="fa fa-spinner fa-spin"></i>
<div class="message">
Loading....
</div>
</div>
</div>
<script type="text/javascript" src="Scripts/require.js" data-main="/App/main"></script>
</body>
</html>
Have anyone ever tried to integrate google plus sign in with Durandal and have this same issue? Help and suggestion is much appreciated!!
For remote async loads under Durandal (or, in other words, under RequireJS), you'll need the async, goog, and propertyParser plugins. See the readme at that link.
As an example, here's what we do for Google Maps:
in the paths property of RequireJS (usually in the main.js file of Durandal), the following order:
'async': '../Scripts/plugins/async',
'propertyParser': '../Scripts/plugins/propertyParser',
'goog': '../Scripts/plugins/goog'
the define, also in the main.js file of Durandal, just before the main function that kicks off the application:
define('jquery', function() { return jQuery; });
define('knockout', ko);
define('gmaps', ['async!http://maps.google.com/maps/api/js?sensor=false'],
function () {
return window.google.maps;
});
define(['durandal/system',
'durandal/app',
'durandal/viewLocator',
'bindings',
'extenders',
'validations'],
function (system, app, viewLocator, bindings, extenders, validations) {
Notice the async! before the remote API URL. Also notice that we don't actually define gmaps for the main entry point of the application. We set up a global define before the main entry point.
Please let me know if that helps.
So I found the solution to integrate the google plus sign in into my Durandal app. You basically need to include asyncJS (don't have to include googJS/propertyParserJS, goog only works for very specific google APIs - (https://developers.google.com/loader/?csw=1#AvailableAPIs) in the require section of main.js and define the google client api in main.js. However, you cannot use the following urls to call the api in your define in main.js.
<script src="https://apis.google.com/js/client:platform.js" async defer> </script>
<script src="https://apis.google.com/js/platform.js?onload=onLoadCallback" async defer></script>
In the Google Plus Sign In Javascript API documentation, you are asked to include the above script tags in your html file. However, this does not work with requireJS and Async. Instead you need to call Google Client API and use the following url in main.js:
define('gapi',['async!https://apis.google.com/js/client.js!onload'], function() {
console.log('gapi loaded: ' + gapi);
return window.gapi;
});
You can then call gapi in your specific viewmodel after doing this by including it in the define section of your viewmodel. To implement the google plus sign in, you can then call the following function after defining and passing in the parameters as specified by the instructions in Google Plus Sign in Javascript API (https://developers.google.com/+/web/signin/javascript-flow):
define(['gapi'], function(gapi) {
return {
additionalParams : {
'callback': "specify a callback function here",
'clientid' :"your client_ID",
'scope' : "scope for permissions",
'cookiepolicy' : "single_host_origin"
},
googlelogin: function() {
gapi.auth.signIn(this.additionalParams);
}
}
});
I then bind the googlelogin method to my google sign in button using
data-bind="click:googlelogin". This will let you sign in using your google plus after clicking the button. However, this method seems to have a problem when it comes to the callback for me. So here is the second alternative which works for me, use the following method to authorize the user and execute the callback (you must define this)when your sign in button is clicked:
gapi.auth.authorize(parameters,signinCallBack);
The parameters are specified here: (https://developers.google.com/api-client-library/javascript/reference/referencedocs#gapiauthauthorize). Hope this helps you integrate your Durandal/RequireJS app with Google Plus and Ouath2 for client side JS implementation! Thank you #EricTaylor for guiding me!
it's days I'm trying to figure out how to make a chrome extension I'm building working...with AngularJS.
Problem is that I cannot successfully access remote resources; as long as I didn't use angular, my way to communicate between the main html and the sandbox was with a pub/sub javascript I found on the web pkg.js and in this way I could call external urls in the main.js and pass retrieved data back to subscribed javascripts.
I have heavily simplified my code so that you can better understand the architecture. Here are some test resources that works perfectly apart from the fact...that angular does not work :/
My manifest has the following relevant parts:
{
...
"background": {
"scripts": ["new/ext/background.js"],
"persistent": false
},
"permissions": [
"tabs",
"http://*.mysite.com/*"
],
"sandbox": {
"pages": [ "new/testmain.html" ]
},
"content_security_policy": "script-src 'self' https://ajax.googleapis.com; object-src 'self'"
}
My background.js is very simple: it just creates a tab and calls an html which will host the angular code:
chrome.browserAction.onClicked.addListener(function (tab) {
chrome.tabs.create({'url': chrome.extension.getURL('/new/main.html')}, function (tab) { });
});
The main.html is, too, pretty easy: just some script includes and the iframe:
<!doctype html>
<html>
<head>
<title>Testing angular</title>
<script type='text/javascript' src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js"></script>
<!-- custom scripts -->
<script type="text/javascript" src="/lib/pkg.js"></script>
</head>
<body style="height: 100%">
<h1>Iframe below</h1>
<iframe id="iframe" src="testmain.html" width="100%" height="100%" frameborder="none"></iframe>
<script type="text/javascript" src="testmain.js"></script>
</body>
</html>
The testmain.js just subscribes to an event and, in case receives it, it publishes dummy data:
iframe = document.getElementById("iframe");
$.pkg.init(iframe.contentWindow);
$.pkg.listen("items", function () {
console.log("[testmain.js] received items message");
items = [
{ name:"foo", age: 12 },
{ name:"bar", age: 11 },
{ name:"mickey", age: 15},
{ name: "donald", age: 27}
];
$.pkg.send("response", [items]);
console.log("[testmain.js] sent response");
});
Now let's come to testmain.html:
<!DOCTYPE html>
<html data-ng-app="App" data-ng-csp>
<head>
<title></title>
</head>
<body ng-controller="TodoCtrl">
<div ng-repeat="item in testitems">
<ul>
<li>{{item.name}}</li>
</ul>
</div>
<script type='text/javascript' src="lib/jquery.min.js"></script>
<script type="text/javascript" src="lib/angular.min.js"></script>
<script src="/lib/pkg.js"></script>
<script src="app/testapp.js"></script>
</body>
</html>
And, finally, here is the testapp.js:
var App = angular.module('App', []);
App.controller('TodoCtrl', function($scope) {
//test
$.pkg.init(window.top);
$.pkg.send("items");
console.log("[testapp.js] sent message items");
$.pkg.listen("response", function(res){
console.log("[testapp.js] received " + res.length + " items");
$scope.testitems = res;
for (i = 0; i < $scope.testitems.length; i++) {
console.log("[testapp.js] testitem: " + $scope.testitems[i].name);
}
});
});
The controller just inits the communication with destination = html containing the iframe. It then sends a message requesting for data which is then sent back (listens).
If I try from the console to run any manual command to get the $scope variable, no success at all:
document.getElementById('iframe')
Sandbox access violation: Blocked a frame at "chrome-extension://jcnppfndabbcgbdcnjncnoddmhmkmmbb" from accessing a frame at "chrome-extension://jcnppfndabbcgbdcnjncnoddmhmkmmbb". The frame being accessed is sandboxed and lacks the "allow-same-origin" flag.
Sandbox access violation: Blocked a frame at "chrome-extension://jcnppfndabbcgbdcnjncnoddmhmkmmbb" from accessing a frame at "chrome-extension://jcnppfndabbcgbdcnjncnoddmhmkmmbb". The frame being accessed is sandboxed and lacks the "allow-same-origin" flag.
Sandbox access violation: Blocked a frame at "chrome-extension://jcnppfndabbcgbdcnjncnoddmhmkmmbb" from accessing a frame at "chrome-extension://jcnppfndabbcgbdcnjncnoddmhmkmmbb". The frame being accessed is sandboxed and lacks the "allow-same-origin" flag.
<iframe id="iframe" src="testmain.html" width="100%" height="100%" frameborder="none"></iframe>
This is what happens in the console:
[testapp.js] sent message items testapp.js:8
[testmain.js] received items message testmain.js:5
[testmain.js] sent response testmain.js:13
[testapp.js] received 4 items testapp.js:10
[testapp.js] testitem: pippo testapp.js:13
[testapp.js] testitem: pluto testapp.js:13
[testapp.js] testitem: paperino testapp.js:13
[testapp.js] testitem: minnie testapp.js:13
as you may notice, communication DO occur, $scope.testitems variable is set correctly. BUT nothing is rendered on the iframe :(
Can anyone help me figure out how to come out of all of this?
Btw, I was in a some way forced to do so - the first version which was on plnkr gladly used the $http inside the controller, but this appears to be prohibited in chrome extensions...
I also tried to use amplifyjs but didn't come to out to make the communication work between an iframe and its container.
Thanks a lot!