Right way to use gapi.client.drive in chrome extension - javascript

I'm trying to use drive to save data from chrome extension.
First, I set needed options to manifest.json
"oauth2": {
"client_id": "999999.apps.googleusercontent.com",
"scopes": [
"https://www.googleapis.com/auth/drive.appdata"
]
},
Then try to get list of files:
$.getScript("https://apis.google.com/js/client.js", function () {
gapi.load('client', function () {
console.log("gapi.client is loaded")
gapi.client.load('drive', 'v3', function () {
console.log("gapi.client.drive is loaded");
chrome.identity.getAuthToken({'interactive': true}, function (token) {
gapi.client.setToken({access_token: token});
console.log("token :", token);
gapi.client.drive.files.list().then(function (list) {
console.log(list)
})
});
});
});
});
Console said:
gapi.client is loaded
gapi.client.drive is loaded
token : [TOKEN]
And the error is like that:
"code": 403,
"message": "The granted scopes do not give access to all of the requested spaces."

The error indicates that you are trying to access unauthorized spaces. Your scope only allows you to use the "appDataFolder" space. Therefore, you have to change
gapi.client.drive.files.list()
for
gapi.client.drive.files.list({spaces:"appDataFolder"}).

Related

Google Analytics Data API - HTML to Apps Script: gapi is not defined

I am trying to execute a Report with the Google Analytics Data API. I built the request using Google's documentation and I get this script. The script works well if I execute it directly with the "Try this method" option in the 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("YOUR_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({
"property": "properties/295880876",
"resource": {
"metrics": [
{
"name": "sessions"
},
{
"name": "conversions"
},
{
"name": "totalRevenue"
}
],
"dimensions": [
{
"name": "week"
},
{
"name": "year"
}
],
"dateRanges": [
{
"startDate": "2021-01-01",
"endDate": "today"
}
]
}
})
.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"});
});
</script>
<button onclick="authenticate().then(loadClient)">authorize and load</button>
<button onclick="execute()">execute</button>
Now I want to run this Script in Apps Script and import the Data to a spreadsheet. However as this is a HTML, if I want to run it as a JS and delete the script tags and content I receive "gapi is not defined".
It is clear that I still have to load https://apis.google.com/js/api.js somehow, but how?
Thanks for your help!
I believe your goal is as follows.
You want to use "Method: properties.runReport" with Google Apps Script.
When I saw your showing script, it seems that it is used for Javascript. In this case, Javascript is different from Google Apps Script. I think that this might be the reason for your issue.
In order to achieve your goal, in the current stage, Advanced Google services can be used. So, in this answer, I would like to propose using AnalyticsData with the Advanced Google services of Google Apps Script.
The sample script is as follows.
Sample script:
Please copy and paste the following script to the script editor of Google Spreadsheet. And, please enable "AnalyticsData" at Advanced Google services. And, please set your property ID to ### of const property = "properties/###";.
function myFunction() {
// Retrieve values from Google Analytics Data API (GA4)
const property = "properties/###"; // Please set your property ID.
const resource = {
"metrics": [
{
"name": "sessions"
},
{
"name": "conversions"
},
{
"name": "totalRevenue"
}
],
"dimensions": [
{
"name": "week"
},
{
"name": "year"
}
],
"dateRanges": [
{
"startDate": "2021-01-01",
"endDate": "today"
}
]
};
const obj = AnalyticsData.Properties.runReport(resource, property);
// Put values to Spreadsheet.
const header = [...obj.dimensionHeaders.map(({ name }) => name), ...obj.metricHeaders.map(({ name }) => name)];
const values = [header, ...obj.rows.map(({ dimensionValues, metricValues }) => [...dimensionValues.map(({ value }) => value), ...metricValues.map(({ value }) => value)])];
const sheetName = "Sheet1"; // Please set the sheet name.
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName)
sheet.getRange(1, 1, values.length, values[0].length).setValues(values);
}
When you run this script, the values are retrieved from "properties.runReport", and the retrieved values are put into the Spreadsheet.
Note:
I cannot know the final result you expect from Now I want to run this Script in Apps Script and import the Data to a spreadsheet.. So, in the above sample script, the retrieved values are put to "Sheet1" as the header of week,year,sessions,conversions,totalRevenue. If you want to change this, please modify this for your actual situation.
Reference:
Method: properties.runReport

Google javascript client api : how to fetch profile name?

I am trying to implement SignIn with Google with redirect approach. I am following this link
My code looks like below
<script src="https://apis.google.com/js/platform.js?onload=startGoogleApp" async defer></script>
<script>
var startGoogleApp = function () {
gapi.load('auth2', function() {
auth2 = gapi.auth2.init({
client_id: '#googleClientId',
ux_mode: 'redirect',
redirect_uri: '#googleRedirectUri',
fetch_basic_profile: true
});
auth2.signIn();
});
}
</script>
But issue is in Google's id_token is not having the name even though I have passed fetch_basic_profile: true I also tried with scope: 'profile'.
I want to fetch name along with email. don't know what am I doing wrong here.
I want it in part of token as it is mentioned in documentation I am following. I don't want fetch name with additional api call. Is it possible?
id_token looks like this
{
"iss": "accounts.google.com",
"azp": "*********",
"aud": "***********",
"sub": "*********",
"hd": "***.com",
"email": "*****#***.com",
"email_verified": true,
"iat": 1599717107,
"exp": 1599720707,
"jti": "*******"
}
Googles Id token is not guaranteed to return all of the profile claims on ever response.
If you want the users profile information then you should go though the Google People API. people.get
// Make sure the client is loaded and sign-in is complete before calling this method.
function execute() {
return gapi.client.people.people.get({
"resourceName": "people/me",
"requestMask.includeField": "addresses",
"sources": [
"READ_SOURCE_TYPE_PROFILE"
]
})
.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"});
});
Code ripped from the try me found on people.get

How to display page visits in my web site using data from Google Analytics?

I have a web site and I want, for every article I publish, to display the number of people who visited that page.
My idea is to show the number of page visits by fetching this data from my Analytics account.
By following the tutorial on Google Analytics to handle reports, I have created a small chunk of code to retrieve a specific page's visits number:
let analytics_api_controller = (function () {
const API_KEY = "<secret>";
const CLIENT_ID = "<secret>";
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(API_KEY);
return gapi.client.load("https://content.googleapis.com/discovery/v1/apis/analyticsreporting/v4/rest")
.then(function () { console.log("GAPI client loaded for API"); },
function (err) { console.error("Error loading GAPI client for API", err); });
}
function execute() {
return gapi.client.analyticsreporting.reports.batchGet({
"resource": {
"reportRequests": [{
"viewId": "<secret>",
"dateRanges": [{
"startDate": "2018-03-01",
"endDate": "2019-05-01"
}],
"metrics": [{ "expression": "ga:pageviews" }],
"dimensions": [{ "name": "ga:pagePath" }],
"dimensionFilterClauses": [{
"filters": [{
"operator": "EXACT",
"dimensionName": "ga:pagePath",
"expressions": ["/articles/2019/05/10/myarticle.html"]
}]
}]
}]
}
}).then(function (response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", response);
}, function (err) {
console.error("Execute error", err);
});
}
function _viewsPerPage(pageUrl) {
return execute();
}
// Ctor
window.addEventListener("load", function(e) {
gapi.load("client:auth2", function () {
gapi.auth2.init({ client_id: CLIENT_ID });
});
this.window.setTimeout(function() {
authenticate().then(loadClient);
}, 2000);
});
return {
viewsPerPage: _viewsPerPage
};
})();
The setTimeout is something I added to quickly workaround some timing issues (I need to wait for the API to load, something I will properly solve later).
Problem
The code works fine and this is what happens:
The page loads.
The code kicks in and I am asked to sign in to give permission to access my Analytics reports from my Google account.
I give consent.
In F12 tools I manually run: analytics_api_controller.viewsPerPage(), which gives me the report in the console.
The problem is point 2! Every single time I load the page, I am asked to sign in and give permission. This thing is supposed to go in production, so every user will be prompted to access my Analytics info? I assume if they try they'll fail...
Why am I asked to sign in to use this API?
Am I using the correct API to solve this issue?
I think I am not really understanding how I am supposed to use the Google Analytics API. What am I doing wrong? How should this objective be addressed?
You used a Client-side Application that requires the users to login to access your google analytics data. You should use a Service Application that allows your app to login and access your google analytics data (server-side).
PHP quickstart for service accounts

google sheets gives the option of using apikey for javascript but does not work

i am trying to send four points of data to a spread sheet from a website i am developing. name, email, subject, message.
function loadClient() {
gapi.client.setApiKey(myapikey);
return gapi.client.load("https://content.googleapis.com/discovery/v1/apis/sheets/v4/rest")
.then(function() {
console.log("GAPI client loaded for API");
}, function(error) {
console.error("Error loading GAPI client for API");
});
}
// Make sure the client is loaded before calling this method.
function execute() {
return gapi.client.sheets.spreadsheets.values.append({
"spreadsheetId": mysheetid,
"range": "a1",
"includeValuesInResponse": "false",
"insertDataOption": "INSERT_ROWS",
"responseDateTimeRenderOption": "SERIAL_NUMBER",
"responseValueRenderOption": "FORMATTED_VALUE",
"valueInputOption": "RAW",
"resource": {
"values": [
[
"test#text.com",
"jimmy clarke",
"subject",
"this is a test email"
]
]
}
})
.then(function(response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", response);
}, function(error) {
console.error("Execute error", error);
});
}
gapi.load("client");
</script>
i expected it to send the data to the google sheet without error.
it tells me that this can only be sent using oauth.
i would prefer not to use oauth. my main pain point is that when i look at the (google made) templates it allows for the use of the api key, though when i run the code i recieve and i receive this error
Object {
result: {…},
body: "{\n \"error\":
{\n \"code\": 401,\n \"message\": \"Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.\",\n \"status\": "UNAUTHENTICATED\"\n }\n}\n", headers: {…}, status: 401, statusText: "Unauthorized" }
Could i have made a mistake in setting it up?
May have found the answer i believe it is due to the fact that i left the
spread sheet as private, which would require the use of the oauth.

You must specify a valid JavaScript API Domain

I need some help with the LinkedIn API. I'm getting the following error:
Uncaught Error: You must specify a valid JavaScript API Domain as part of this key's configuration.
But I already add my domain to the Javascript SDK Domains. My domain is the next one:
http://is01.inthegra-app.com.ar:8083/apex/
LinkedIn take it as a valid one but I still having the same error. The code in my page is this one:
<script type="text/javascript" src="//platform.linkedin.com/in.js">
api_key: API_KEY_HERE;
onLoad: onLinkedInLoad;
authorize: true;
</script>
<script type="text/javascript">
function mandoMensaje(){
onLinkedInLoad();
}
function onLinkedInLoad() {
IN.Event.on(IN, "auth", shareContent);
}
function onSuccess(data) {
console.log(data);
}
function onError(error) {
console.log(error);
}
function shareContent() {
var payload = {
"Content-Type": "application/json",
"x-li-format": "json",
"comment": "Hello world...",
"content": {
"title": "LinkedIn API Test",
"description": "Publish in LinkedIn from HTML and JavaScript",
"submitted-url": "http://www.inthegra.com.ar",
"submitted-image-url": "http://www.inthegra.com.ar/img/logo-inthegra-blanco.png"
},
"visibility": {
"code": "anyone"
}
};
IN.API.Raw("/people/~/shares?format=json")
.method("POST")
.body(JSON.stringify(payload))
.result(onSuccess)
.error(onError);
}
</script>
/apex/ is not part of the hostname/domain and port that your Javascript is being executed from. Try removing that portion of the value in your application's configuration.

Categories