I have been researching the google analytics api (GA4) for the past day. And I want to be able to use GA4 api functions like runReport on the client-side. There is a piece of analytics that I want each of my web-clients to see.
Here is the code that I pulled out from the gapi documentation.
<script src="https://apis.google.com/js/api.js"></script>
<script>
/**
* Sample JavaScript code for analyticsdata.properties.runReport
* See instructions for running APIs Explorer code samples locally:
* https://developers.google.com/explorer-help/code-samples#javascript
*/
function authenticate() {
return gapi.auth2.getAuthInstance()
.signIn({scope: "https://www.googleapis.com/auth/analytics https://www.googleapis.com/auth/analytics.readonly"})
.then(function() { console.log("Sign-in successful"); },
function(err) { console.error("Error signing in", err); });
}
function loadClient() {
gapi.client.setApiKey("FILLED_THIS_WITH_MY_API_KEY");
return gapi.client.load("https://analyticsdata.googleapis.com/$discovery/rest?version=v1beta")
.then(function() { console.log("GAPI client loaded for API"); },
function(err) { console.error("Error loading GAPI client for API", err); });
}
// Make sure the client is loaded and sign-in is complete before calling this method.
function execute() {
return gapi.client.analyticsdata.properties.runReport({
"resource": {}
})
.then(function(response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", response);
},
function(err) { console.error("Execute error", err); });
}
gapi.load("client:auth2", function() {
gapi.auth2.init({client_id: "FILLED_THIS_WITH_MY_CLIENT_ID"});
});
</script>
<button onclick="authenticate().then(loadClient)">authorize and load</button>
<button onclick="execute()">execute</button>
And it gives me this error:
gapi.auth2.ExternallyVisibleError: Invalid cookiePolicy\
Related
I'm trying to figure out how to use Google's API service, and I have a client and API key for Google OAuth. Specifically, though I want to check a user's organization, and then echo out some info for them. I understand that that info will be visible with a simple CTRL-SHIFT-I or CTRL-U, but that doesn't matter to me right now. Thanks for your help in advance (JavaScript because I want to try to host this on GitHub pages)!
Here's a Google example I've tried, and I just get error 400's (client and API keys have been deleted).
// Enter an API key from the Google API Console:
// https://console.developers.google.com/apis/credentials
var apiKey = 'AIzaSyDyyNLwHpVqy88tRamPt1NbyVWFzYkLuhA';
// Enter the API Discovery Docs that describes the APIs you want to
// access. In this example, we are accessing the People API, so we load
// Discovery Doc found here: https://developers.google.com/people/api/rest/
var discoveryDocs = ["https://people.googleapis.com/$discovery/rest?version=v1"];
// Enter a client ID for a web application from the Google API Console:
// https://console.developers.google.com/apis/credentials?project=_
// In your API Console project, add a JavaScript origin that corresponds
// to the domain where you will be running the script .apps.googleusercontent.com.
var clientId = '873243932753-jfebiqi1ja0b9a2jiqdiirb8vtjlk4n9.apps.googleusercontent.com.apps.googleusercontent.com';
// Enter one or more authorization scopes. Refer to the documentation for
// the API or https://developers.google.com/people/v1/how-tos/authorizing
// for details.
var scopes = 'profile';
var authorizeButton = document.getElementById('authorize-button');
var signoutButton = document.getElementById('signout-button');
function handleClientLoad() {
// Load the API client and auth2 library
gapi.load('client:auth2', initClient);
}
function initClient() {
gapi.client.init({
apiKey: apiKey,
discoveryDocs: discoveryDocs,
clientId: clientId,
scope: scopes
}).then(function() {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
authorizeButton.onclick = handleAuthClick;
signoutButton.onclick = handleSignoutClick;
});
}
function updateSigninStatus(isSignedIn) {
if (isSignedIn) {
authorizeButton.style.display = 'none';
signoutButton.style.display = 'block';
makeApiCall();
} else {
authorizeButton.style.display = 'block';
signoutButton.style.display = 'none';
}
}
function handleAuthClick(event) {
gapi.auth2.getAuthInstance().signIn();
}
function handleSignoutClick(event) {
gapi.auth2.getAuthInstance().signOut();
}
// Load the API and make an API call. Display the results on the screen.
function makeApiCall() {
gapi.client.people.people.get({
'resourceName': 'people/me',
'requestMask.includeField': 'person.names'
}).then(function(resp) {
var p = document.createElement('p');
var name = resp.result.names[0].givenName;
p.appendChild(document.createTextNode('Hello, ' + name + '!'));
document.getElementById('content').appendChild(p);
});
}
<p>Say hello using the People API.</p>
<!--Add buttons to initiate auth sequence and sign out-->
<button id="authorize-button">Authorize</button>
<button id="signout-button">Sign Out</button>
<div id="content"></div>
<script async defer src="https://apis.google.com/js/api.js" onload="this.onload=function(){};handleClientLoad()" onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>
Edit: I found out that this needs to be done with Admin SDK. Still a bit confused on how to do this though.
As you mentioned this needs to be done using the Admin sdk API. under the users > get section you can try that API and it will provide you an example about how to use it on JS.
function authenticate() {
return gapi.auth2.getAuthInstance()
.signIn({scope: "https://www.googleapis.com/auth/admin.directory.user https://www.googleapis.com/auth/admin.directory.user.readonly"})
.then(function() { console.log("Sign-in successful"); },
function(err) { console.error("Error signing in", err); });
}
function loadClient() {
gapi.client.setApiKey("YOUR_API_KEY");
return gapi.client.load("https://content.googleapis.com/discovery/v1/apis/admin/directory_v1/rest")
.then(function() { console.log("GAPI client loaded for API"); },
function(err) { console.error("Error loading GAPI client for API", err); });
}
// Make sure the client is loaded and sign-in is complete before calling this method.
function execute() {
return gapi.client.directory.users.get({
"userKey": "<user email address>"
})
.then(function(response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", response);
},
function(err) { console.error("Execute error", err); });
}
gapi.load("client:auth2", function() {
gapi.auth2.init({client_id: "YOUR_CLIENT_ID"});
});`
Also I recommend you to to use the Quickstart to get more familiar about how to use the Google API's.
Good day.
I implement on the site a subscription for push notifications.
I can not figure out what the difference between the two approaches.
The first is to simply get the token and send it to the server, then send messages by accessing it
function subscribe() {
// запрашиваем разрешение на получение уведомлений
messaging.requestPermission()
.then(function () {
// получаем ID устройства
messaging.getToken()
.then(function (currentToken) {
console.log(currentToken);
if (currentToken) {
sendTokenToServer(currentToken);
} else {
console.warn('Не удалось получить токен.');
setTokenSentToServer(false);
}
})
.catch(function (err) {
console.warn('При получении токена произошла ошибка.', err);
setTokenSentToServer(false);
});
})
.catch(function (err) {
console.warn('Не удалось получить разрешение на показ уведомлений.', err);
});
}
The second is to get the object PushSubscription and use what he returned to send messages
function subscribeUserToPush() {
return navigator.serviceWorker.register('service-worker.js')
.then(function(registration) {
var subscribeOptions = {
userVisibleOnly: true,
applicationServerKey: btoa(
'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U'
)
};
return registration.pushManager.subscribe(subscribeOptions);
})
.then(function(pushSubscription) {
console.log('PushSubscription: ', JSON.stringify(pushSubscription));
return pushSubscription;
});
}
{
"endpoint": "https://domain.pushservice.com/some-id",
"keys": {
"p256dh":
"BIPUL12DLfytvTajnryr3PJdAgXS3HGMlLqndGcJGabyhHheJYlNGCeXl1dn18gSJ1WArAPIxr4gK0_dQds4yiI=",
"auth":"FPssMOQPmLmXWmdSTdbKVw=="
}
}
The first one is only for Google Firebase, the second one is the Web Standard API. I would highly recommend using the second one.
Here you are the main problems you can run into. link
I'm trying to get protected playback of offline content within Electron.
I'm trying to use:
https://github.com/castlabs/downstream_electron
along with their Widevine-compatible Electron build: https://github.com/castlabs/electron-releases/releases/tag/v1.8.7-hdcp-vmp1010
Which should, according to downstream_electron's README.md, "allow protected playback of offline content within Electron".
I have a proof-of-concept set up with dashjs where I can extract the session information and download a drm-protected dash manifest, along with the audio and video segments.
I'm using publicly available assets from ezdrm:
manifest: http://wvm.ezdrm.com/demo/stream.mpd
license server: http://widevine-dash.ezdrm.com/proxy?pX=BF9CEB
When I call DownstreamElectronFE.downloads.getOfflineLink() after downloading the asset, it gives me back this:
{
offlineLink:"http://127.0.0.1:3010/movies/6441406178546155520/stream.mpd"
persistent:"F75D9FC450010B582A7951ED228DAF85"
}
So I've got a local, drm-protected manifest being served from a local server. How do I get "protected playback of offline content within Electron"?
If I were to provide this offlineLink value as the source to a dash video player, it would still need to reach out to the internet to talk to the license server, so it wouldn't be truly offline.
A portion of my demo is below:
const dashjs = require('dashjs');
let session
function FakePersistentPlugin() {
this.createPersistentSession = (persistentConfig) => {
console.log('create - call of fake persistent plugin, persistentConfig', persistentConfig);
return new Promise((resolve) => {
setTimeout(function () {
console.log('resolving session',session.sessionId)
resolve(session.sessionId);
}, 5000);
});
};
this.removePersistentSession = (sessionId) => {
console.log('remove - call of fake persistent plugin, sessionId', sessionId);
return new Promise((resolve) => {
setTimeout(() => {
console.log('remove - call of fake persistent plugin resolved', sessionId);
resolve();
}, 5000);
});
};
}
const downstreamElectron = require("downstream-electron/dist").init(window,new FakePersistentPlugin());
console.log('downstreamElectron is ',downstreamElectron);
var player = dashjs.MediaPlayer().create();
player.setProtectionData({'com.widevine.alpha':{serverURL:'http://widevine-dash.ezdrm.com/proxy?pX=BF9CEB'}});
player.initialize(document.querySelector("#videoPlayer"))
player.attachSource('http://wvm.ezdrm.com/demo/stream.mpd')
player.play()
player.on( dashjs.MediaPlayer.events.KEY_SESSION_CREATED, (e) => {
session = e.data.session;
console.log('session is ',session)
});
const config = {
licenseUrl:'http://widevine-dash.ezdrm.com/proxy?pX=BF9CEB',
serverCertificate: new Uint8Array([0])
}
let manifestId
let persistId
function onProgress (err, stats) {
if (err) {
console.logs('on progress err', err, stats);
}
console.log('on progress ',stats);
};
function onFinish (err, info) {
if (err) {
console.log("onFinish error", err);
} else {
console.log("onFinish success", info);
downstreamElectron.downloads.getOfflineLink(info.manifestInfo.id)
.then(
function onSuccess(result) {console.log("offlineLink success", result)},
function onError(err) {console.log("error", err)
})
}
};
downstreamElectron.downloads.create('http://wvm.ezdrm.com/demo/stream.mpd')
.then(
function onSuccess(result) {
console.log("create success", result)
manifestId = result.id
downstreamElectron.downloads.createPersistent(manifestId,config)
.then(
(result)=>{
console.log("createPersistent success",result)
persistId = result
downstreamElectron.downloads.savePersistent(manifestId,persistId)
.then(
() => {
console.log('savePersistent success')
downstreamElectron.downloads.start(manifestId,{video:['video/avc1'],audio:['audio/und/mp4a']})
.then(
function onSuccess() {console.log("start success")},
function onError(err) {console.log("start error", err)
})
downstreamElectron.downloads.subscribe(manifestId, 1000, onProgress, onFinish)
.then(
function onSuccess() {console.log("subscribed successfully")},
function onError(err) {console.log("subscribe error", err)
})
},
(err) => {
console.log('savePersistent error',err)
}
)
},
(err)=>{
console.log("createPersistent error",err)
}
)
},
function onError(err) {console.log("create error", err)}
)
You need to request the license ahead of time, and specifically request a license that allows persistence (offline use). Basically, you ned to trigger the license request, before going offline. There might be a function call to do this somewhere, otherwise you could start playback to get the license, and terminate it afterwards.
Note that the license issued has to allow offline usage, that is not the default. The EZDRM demo stuff, might allow you to request such a license, but it is not likely to give you one like that by default.
I am basically caching an offline page and loading it when my website is offline.
For this I have created a page say 'signIn' and the javascript file of 'SignIn' is javascript->pages->signIn here I have initiated the service worker like
javascript/page/script.js
if('serviceWorker' in navigator){
navigator.serviceWorker.register('./sw1.js').then(function(reg){
console.log("Service workers registered");
});
}
else{
console.log("Browser doesnt support service workers");
}
})
The sw1.js and the offline.html is basically in the same folder as the page SignIn.
self.addEventListener('install', function(event) {
var offlineRequest = new Request('./offline.html');
event.waitUntil(
fetch(offlineRequest).then(function(response) {
return caches.open('offline').then(function(cache) {
console.log('[oninstall] Cached offline page', response.url);
return cache.put(offlineRequest, response);
});
})
);
});
self.addEventListener('fetch', function(event) {
var request = event.request;
if (request.method === 'GET') {
console.log(request);
event.respondWith(
fetch(request).then(function(response){
console.log("From Network "+response);
return response;
}).catch(function(error) {
console.log(
'[onfetch] Failed. Serving cached offline fallback ' +
error
);
return caches.open('offline').then(function(cache) {
console.log("Opened Cache");
return cache.match('./offline.html');
});
})
);
}
});
Basically things work fine when I am online but When i am offline I get the following error in chrome-dev-tools-applications .
Please Help me.
I am trying to get LinkedIn Access Token after login. Login is working fine with JavaScript SDK and I'm able to receive "oauth_token" and member_id. I need access_token to verify the email address (if it is not forged on the way).
Below is my script:
<script>
function LoginWithLinkedIn() {
IN.User.authorize(afterAuthorization);
}
function afterAuthorization(response){
debugger
if(IN.User.isAuthorized()==true){
getProfileData();
}
}
function onSuccess(data) {
console.log(data);
}
function onError(error) {
console.log(error);
}
function getProfileData(r) {
IN.API.Profile("me")
.fields("id,firstName,lastName,email-address,picture-urls::(original),public-profile-url,location:(name)")
.result(onSuccess)
.error(onError);
}
</script>
I need help getting the access_token after successful authorization. Any help is highly appreciated!
Thanks!
Hope following code will work
function LinkedInLogin() {
IN.User.authorize(getProfileData);
}
function onSuccess(data) {
jQuery('#hdnAccessToken').val(IN.ENV.auth.oauth_token);
try {
jQuery('#hdnSocialLoginType').val('in');
jQuery('#HiddenFieldUserId').val(data.values[0].id);
jQuery('#HiddenFieldEmail').val(data.values[0].emailAddress);
jQuery('#HiddenFieldFirstName').val(data.values[0].firstName);
jQuery('#HiddenFieldLastName').val(data.values[0].lastName);
jQuery('#HiddenFieldType').val('linkedin');
jQuery('#BtnLoginSocial').click();
}
catch (err) {
alert(jQuery('#HiddenErrorMessage').val());
}
//console.log(data);
}
function onError(error) {
console.log(error);
}
function getProfileData() {
if (IN.User.isAuthorized() == true) {
IN.API.Profile("me").fields("id,firstName,lastName,email-address").result(onSuccess).error(onError);
}
}