Connect Google Spreadsheets API V4 (spreadsheets.values.get) with Private Sheets - javascript

Request:
I need to Connect a Service using JS with a Private Google Sheet. It's not needed to get the end user to sign in into a Google Account, I only need to show some data from that Private Google Sheet into the Web page.
I already have a Key and a Client ID which I use following these steps https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/get
It works so far, the issue that I have with my request is that this sample get the end user to sign in into a Google account to then make the Api Call.
NOTE: if the Google Sheet is Shareable by a link then I can connect with the Key, however the Google Sheet should be private to only grant access to some people.
Is there a way to only consume the data from the Private Google Sheet without to get the end user sign in into the Google Account?

As suggested in the comments, you can use a Web App as an API to make a get or post request from your JavaScript application, in order to not need credentials/token for those requests you need to deploy the web app with the option "who has acces to the app" set to "anyone, even anonymous" and the option "Execute as" set to "me" so it can be run under your credentials. An example of a simple web app to which you can do a get request to the deployed url is below:
function doGet() {
var spreadsheet = SpreadsheetApp.openById("[SPREADSHEET-ID]");
var sheet = spreadsheet.getSheetByName("Sheet1");
var values = sheet.getRange("A2:E6").getValues();
var stringOutput = values.toString();
return ContentService.createTextOutput(stringOutput);
}
This will retrieve the values from the "A2:E6" range as a string.

Related

Using Google Sheet's v4 JSON Endpoint with my API but still getting "Unauthorized" message

I am trying to get a simple JSON package from putting the URL of my Google spreadsheet so I can use it on my webpage; I am using my Google Cloud Console API as it is said on the documentation of the v4 Google API format, but I still get the error of "Unauthorized API"
Documentation: https://developers.google.com/sheets/api/guides/migration#v4-api
I am using this URL:
https://sheets.googleapis.com/v4/spreadsheets/SHEET_ID/values/Sheet1?key=API_KEY
My google sheet is set as published on the web. And also I am the creator of the google sheet.
What could I be missing? I am new to API's!
First Edit:
Answering the comment of ABDULLOKH MUKHAMMADJONOV
Here is the code I am using to make a GET request to the google sheet, you can see the Sheet ID is there, and also the API of the google cloud platform.
fetch("https://sheets.googleapis.com/v4/spreadsheets/1S652uS2FLVoZ1m3apb6R4H783v6GkV58HbQ6Idec5aY/values/Sheet1?key=AIzaSyCpFZ7mcqMNc6Q_bP6h1kCEfAi6c_fd8AM", {"method": "get"})
.then( (httpResponse) => {
if (httpResponse.ok) {
console.log(httpResponse.json());
return httpResponse.json();
} else {
return Promise.reject("Fetch did not succeed");
}
} )
.then(json => console.log(json.someKey))
.catch(err => console.log(err));
This code is from the Wix code editor.
The caller doesnt not have permissions
Means that the user you are authenticated as does not have permission to do what it is you are trying to do.
The method
https://sheets.googleapis.com/v4/spreadsheets/SHEET_ID/values/Sheet1?key=API_KEY
I believe is this method spreadsheets.values/get if you check the documentation you will notice that it requires authorization with one of these scopes
You appear to only be sending an api key. You need to be authorized to access that sheet. You cant access it with an API key that only grants access to public data.
Ok, so I investigated about the OAuth 2.0 authentication and authorization for using Google Sheet's REST API. I added one of the needed scopes.
But I am stuck at the point on how to do the authorization process...
I am looking at this google documentation - How to use Google OAuth 2.0 authorization
But I haven't been able to get to the answer I seek. I am stuck at the part where it says "When your application needs access to user data, it asks Google for a particular scope of access." I do now know how to code this request or to do this request through the Insomnia software.
I am trying to do the GET request with a wix testing website, and also with Insomnia, but I haven't been able to achieve it.
These are the images from Insomnia, which tell me "Invalid authorization URL"
Insomnia's OAuth 2.0 authentication parameters
Insomnia's API Query parameter

Trouble accessing a googlesheet using API created by someone else and only shared to specific persons

Our supplier maintains a Googlesheet and we are trying to add a form on our website that accesses that sheet and pulls data from it. Very simple task but we are having trouble with OAuth. The sheet is not public and only shared with certain people (including my Google ID).
Now, I used Google Developer Console to setup the Googlesheets API library. I added a simple form which is here: https://alcocovers.com/knowledge-base/track-your-order/. When I first used the form, I clicked on the "sign in" button (currently hidden), it showed me the consent form in a popup, I signed in using my Google ID and it asked "alcocovers.com wants access to my profile info" and I gave access. The form started to work and I could pull information from the sheet and show on our web page.
But the problem is, the authentication I did to link the website to access my Google account (and the google sheet) doesn't work for everyone. If I use the form in incognito mode, it fails to access the sheet that means everyone who uses the form has to give consent. That doesn't make sense because I thought when I signed in first time and gave the website access to my account and sheet, it will work for everyone. It's the website making the access not the individual user. We want the users of our site to be able to use the form and pull data from the sheet. How can I achieve this?
Below is the code I am using to initialize and authenticate the client. This code is copy pasted from the Google Sheet API documentation. I am assuming this needs to change so the OAuth only happens once which is already done linking the site to the sheet and on future form use, no consent should be needed.
function initClient() {
var API_KEY = ''; // I added api key here
var CLIENT_ID = ''; // I added client id here
var SCOPE = 'https://www.googleapis.com/auth/spreadsheets.readonly';
gapi.client.init({
'apiKey': API_KEY,
'clientId': CLIENT_ID,
'scope': SCOPE,
'discoveryDocs': ['https://sheets.googleapis.com/$discovery/rest?version=v4'],
}).then(function() {
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSignInStatus);
updateSignInStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
});
}
function handleClientLoad() {
gapi.load('client:auth2', initClient);
}
function updateSignInStatus(isSignedIn) {
if (isSignedIn) {
makeApiCall();
}
}
function handleSignInClick(event) {
gapi.auth2.getAuthInstance().signIn();
}
function handleSignOutClick(event) {
gapi.auth2.getAuthInstance().signOut();
}
Update #1:
After trying the solution suggested by #Jescanellas, I am getting following error. Note, I kept the same API key, only changed the CLIENT ID.
The other users cannot use your credentials to access the Sheet. In order to do that you need to use a Service Account. Once you create it you can use your Google Account to make the authorized calls to the API with Domain-Wide Delegation, by using the Service Account credentials instead of yours. Follow the steps from the documentation:
1 - Create the service account and credentials
Open the Service accounts page. If prompted, select a project.
Click add Create Service Account, enter a name and description for
the service account. You can use the default service account ID, or
choose a different, unique one. When done click Create.
The Service account permissions (optional) section that follows is
not required. Click Continue.
On the Grant users access to this service account screen, scroll
down to the Create key section. Click add Create key.
In the side panel that appears, select the format for your key: JSON
is recommended.
Click Create. Your new public/private key pair is generated and
downloaded to your machine; it serves as the only copy of this key.
For information on how to store it securely, see Managing service
account keys.
Click Close on the Private key saved to your computer dialog, then
click Done to return to the table of your service accounts.
2 - To enable G Suite domain-wide delegation:
Locate the newly-created service account in the table. Under
Actions, click show more, then Edit.
In the service account details, click Show domain-wide
delegation, then ensure the Enable G Suite Domain-wide Delegation
checkbox is checked.
If you haven't yet configured your app's OAuth consent screen, you
must do so before you can enable domain-wide delegation. Follow the
on-screen instructions to configure the OAuth consent screen, then
repeat the above steps and re-check the checkbox.
Click Save to update the service account, and return to the table of
service accounts. A new column, Domain-wide delegation, can be seen.
Click View Client ID, to obtain and make a note of the client ID.
As said before, use the Service Account credentials to access the Sheet.

Authenticate with Google as a specific User ID

I have set up Google Drive UI integration with my web app. When a user chooses to create a new file in Drive using my app, they are sent to
https://[mysite]?state={"folderId": "...", "action": "create", "userId":"..."}
I am signed in to multiple Google accounts (A and B) in my browser.
Account A opts to create a file, and is sent to my app with "userId": "[A's user id]" in the url.
However, with the gapi.auth2 JS library:
authInstance.signIn()
// Listen for sign in, and then:
authInstance.currentUser.get().getAuthResponse().access_token
Returns an access token for Account B.
This causes 404 errors when I try to create a file in folderId, which is only accessible to Account A.
How can my app authenticate with Google as the specific userId that opted to create a file?
The docs for Drive UI Integration do not seem to cover this issue, and the docs for Google Sign-In for Websites do not (as far as I can tell) provide a way to specify which account I want to sign in with (except through broad filters like "use a specific G Suite domain").
Update: The HTTP Google OAuth docs allow the client to specify a login_hint, which is an "email address or sub identifier" – it is not entirely clear what a "sub identifier" is. And, strangely, the Javascript API docs imply that login_hint is a response parameter, not something I can set.
Update 2 userId is an opaque Google-provoded integer value that I don't recognise. My app, Including the Drive upload, is fully client-side in JS and has no long-term data storage.

Display Google Analytics data on my web site?

I'm trying to figure out a way to display data collected from Google Analytics on my web site. I'm using NopCommerce, and I want to display this information/statistics in a view in the Admin Section.
There might be many ways to achieve this, and after searching the web I found some examples using JavaScript, but I couldn't find a good tutorial for this.
I have also looked into integrating Google Analytics with C#, and I found this example: http://biasecurities.com/2012/02/using-the-google-analytics-api-with-asp-net-mvc/#comment-1310
A demo project can be downloaded from GitHub here: https://github.com/jgeurts/Analytics-Example
However the demo project doesn't seem to work as the google URL (https://www.google.com/analytics/feeds/accounts/default) is no longer in use.
As I'm using a MVC application it would be preferable to make this happen by applying the Google Analytics logic within a Controller and displaying it in a view. Or something like that.
Google provides a query tool to experiment with here, so it shouldn't be to hard extracting data from Google Analytics and display the data on the website: https://ga-dev-tools.appspot.com/explorer/
Has anyone been able to successfully display Google Analytics data on their website?
In case some one else is having the same problem here's what I did and it pretty much answers the question.
1.
Here is the basic code for a API client that access data from Google Analytics via your Google Service Account. https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth#service_account
In order to make this application work you need to have several things ready before you start coding.
*Google Analytics Account - once registered a "tracker" code is generated for you to put on each webpage you want to track. You may not see any statistics right away and it can take up to 24h before any statistics are shown in the Google Analytics Dashboard.
An OAuth Authorisation (API-Key) with CLIENT_ID, CLIENT SECRET and EMAIL ADRESS (This is not your normal email but a service account email that is created for you when you make an OAuth Authorisation).
console.developers.google.com/
A serverkey, can also be created here: console.developers.google.com/.
You can also create a browser key, haven't bothered with that though and don't know what it does.
Finally you need a certificate key. Your application will only be able to access your Google Analytics account by using the key and credentials. The key is an encrypted p.12 file. You can find the key in https://code.google.com/apis/console/.
Here is a guide for the key: http://www.pimcore.org/wiki/display/PIMCORE/Setup+Google+Analytics+Reporting+with+OAuth2+Service+Accounts+(since+1.4.6)
2.
Now that you have all keys and credentials you need it is time to start looking at the code I linked in "1". Here is the basic for it again: https://developers.google.com/api-client-library/dotnet/guide/aaa_oauth#service_account
Create a console application and implement the code above.
Note: your not making a "Google Plus service" so you have to change those parts for "AnalyticsService". Go to manage nuget and install packages:
Google Apis Core Library
Google Apis Client Library
Google Apis Auth Client Library
Google Apis Analytics.v3 Library
Google GData Client (This provides properties used to query data, metrics, demensions etc)
Google GData Extensions Library
Analytics
Might forgot something but here are the namespaces I use:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography.X509Certificates;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Analytics.v3;
3
Finally, here's is some of my code. Note I'm creating a new Analytics as supposed to "new ServiceAccountCredentials" as in the code from Google. That's the main difference:
Retrieve data from Google Analytics API with .NET, multiple metrics?
With this I'm able to access and query data from Google Analytics account. The best part is that you don't have to log in to Google for this as the key and credentials gives you access to the account data directly.
I will migrate this code to MVC now I might make an update later on for how to implement this Analytics client in Mvc.
This document explains how to get Google Access tokens and use them to get Google Analytics data to be displayed in our websites.
Example: A live example is available in
https://newtonjoshua.com
Note: Use the same Gmail account for all the below steps.
STEP 1: Set Up Google Analytics
Follow the below steps to set up Google Analytics on your website
Sign in to your Analytics account.
Select the Admin tab.
Select an account from the drop-down menu in the ACCOUNT column.
Select a property from the drop-down menu in the PROPERTY column.
Under PROPERTY, click Tracking Info -> Tracking Code.
To collect data, you must copy and paste the Analytics tracking code
into the source code on every web page you wish to track.
Once you have the JavaScript tracking code snippet for your
property, copy the snippet exactly without editing it.
Paste your tracking code snippet (unaltered, in its entirety) before
the closing </head> tag on every web page on your site you wish to
track.
Once you have successfully installed Analytics tracking, it may take
up to 24 hours for data such as traffic referral information, user
characteristics, and browsing information to appear in your reports
Refer to:
https://support.google.com/analytics/answer/1008080?hl=en
https://analytics.google.com
STEP 2: Get Tokens
Google Project:
To create a Google Cloud Platform project, open the Google Developers Console (https://console.developers.google.com) and click Create Project.
Enable OAuth 2.0 API access:
Your application will need to access user data and contact other Google services on your behalf. Use OAuth 2.0 to grant your app API access.
To enable that, you need a client ID:
Open the Google API Console Credentials page (https://console.developers.google.com/apis/credentials).
From the project, drop-down and select your project.
Select Create credentials and choose OAuth client ID.
Under Application type, select Web application, enter a Name and
set the Restrictions by entering JavaScript origins, Redirect URIs to point the website where you are planning to display the data, and then click Create.
Make note of the OAuth 2.0 client_id and client_secret. You will need them to configure the UI.
Get Authorization code:
Enter in browser:
https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/analytics.readonly&response_type=code&client_id={{
client_id}}&redirect_uri={{redirect_uri }}
&approval_prompt=force&access_type=offline
You will get redirected to
{{redirect_uri }}?code=={{authorization_code}}#
Get Refresh Token:
Send a POST request, possibly via a REST console to
https://www.googleapis.com/oauth2/v3/token?code={{authorization_code}}
&client_id={{client_id}}&client_secret={{client_secret}}
&redirect_uri={{redirect_uri }}&grant_type=authorization_code
You will get a JSON response with
{"refresh_token": refresh_token}
You can use the refresh token to get access token to access to Google APIs.
Get the Access Token:
Send a POST request to,
https://www.googleapis.com/oauth2/v3/token?client_id={{client_id}}
&client_secret={{client_id}}
&grant_type=refresh_token&refresh_token={{refresh_token}}
You will get a JSON with access_token in the response.
{access_token: {{access_token}}}
Example:
var access_token = '';
function getAccessToken(){
$.post('https://www.googleapis.com/oauth2/v3/token', {
client_id: {{client_id}},
client_secret: {{client_secret}},
grant_type: 'refresh_token',
refresh_token: {{refresh_token}}
}, function (data, status) {
if (status === 'success') {
access_token = data.access_token;
// Do something eith the access_token
}
else {
console.error(status);
}
});
}
Check Token validity:
Send a POST request to,
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token={{access_token}}
Example:
function checkValidity() {
$.post('https://www.googleapis.com/oauth2/v1/tokeninfo', {
access_token:{{access_token}}
}).done(function (data, status) {
if (status === 'success') {
console.debug(data.expires_in);
var check = false;
check = data.hasOwnProperty('expires_in');
if (check) {
// Token is valid
}
if (!check) {
getAccessToken();
}
}
else {
console.debug(status);
}
})
.fail(function (data) {
console.error(data);
getAccessToken();
});
}
Step 3: Fetch Data
Embed API:
The GA Embed API is a JavaScript library that allows you to easily create and embed your GA dashboard on your website in a matter of minutes.
Refer to https://developers.google.com/analytics/devguides/reporting/embed/v1/getting-started.
Query Explorer:
Visit Embed API Query Explorer and authorize
https://ga-dev-tools.appspot.com/query-explorer/
Select the view for which you want to fetch the data.
Select the required metrics and dimensions.
Example:
Get Country Data (I want to know the number of users accessing my website from each country).
To get that data, select the metrics as 'users' and the dimensions as 'country'.
Click on Run Query.
You will find the analytics data for the query displayed in a table.
Copy the API Query URI. And add access_token={{access_token}} to the URI.
Example:
https://www.googleapis.com/analytics/v3/data/ga?ids={{ids}}&start-date=2015-07-01&end-date=today&metrics=ga%3Ausers&dimensions=ga%3Acountry&access_token={{access_token}}
Send POST request to the URIs to get the data in your browser.
Example:
function gaGetCountry() {
$.get('https://www.googleapis.com/analytics/v3/data/ga?' +
'ids={{ids}}' +
'start-date=2015-07-01&' +
'end-date=today&' +
'metrics=ga%3Ausers&' +
'dimensions=ga%3Acountry&' +
'sort=ga%3Ausers&' +
'filters=ga%3Ausers%3E10&' +
'max-results=50' +
'&access_token=' + {{access_token}},
function (data, status) {
if (status === 'success') {
// Display the Data
drawRegionsMap(data.rows);
} else {
console.debug(status);
}
});
}
Step 4: Display Data
Now we have gathered the data. Finally we have to display them on our website.
"Display live data on your site" is the title of Google Charts. And that is what we are going to do.
Refer to https://developers.google.com/chart/.
The following example will draw a GeoChart in the div with id='countryChart'.
// Draw country chart
function drawRegionsMap(data) {
var head = data[0];
head[0] = 'Country';
head[1] = 'Users';
for (var i = 1; i < data.length; i++) {
var d = data[i];
d[1] = Number(d[1]);
}
var chartData = google.visualization.arrayToDataTable(data);
var options = {
title: 'My Website is viewed from,',
domain: '{{Country Code eg: IN for India}}',
tooltip: {
textStyle: {
color: 'navy'
},
showColorCode: true
},
legend: {
textStyle: {
color: 'navy',
fontSize: 12
}
},
colorAxis: {
colors: ['#00FFFF', '#0000FF']
}
};
var chart = new google.visualization.GeoChart(document.getElementById('countryChart'));
chart.draw(chartData, options);
}
Refer to https://newtonjoshua.com to view the above example in action.
I'd recommend to use the new Google APIs Client Library for .NET (currently in beta). Information about the Analytics API can be found here. Note that the Client Library for .NET (google-api-dotnet-client) supersedes the .NET library for the Google Data API (google-gdata).
Unfortunately, there is no sample code available yet from Google (see this issue) but this question on SO should help.
If you don't want to login every time you access Analytics data, you can use OAuth 2.0 authorization with offline access. You have to grant initial access to your web application, though. This requires you to login once but you can use a refresh token later on.
To date, the easiest solution is to create a report of your Google Analytics data in Google Data Studio (free, native connector to GA), and share that report to embed in an <iframe>
See details on https://support.google.com/datastudio/answer/7450249?hl=en
You get
flexible vizualisation
security and control on the data being shared
0 code nor maintenance
result is being cached for better performance
I spent a couple of days trawling the Internet to get some sample ASP.NET code with no luck. I used Koffe14's method for authentication, and also Linda Lawton's excellent ASP.NET analytics example.
I've posted the code on my website. It's not MVC, but it might help other people who need to get data from Google analytics into an ASP.NET web page using the v3 Google API.
Check out embeddedanalytics.com (disclaimer - I work with them).
This is a simple yet powerful solution geared for people that don't want deal with learning the GA API and then having to link it to visualization (e.g. charts/graphs).
Basically define your charts and embed a snippet of code where you want the chart to show. We also support mechanisms so that it is easy to integrate into a custom built CMS or other web portal.

Google Sites. JS connection with spreadsheet

Using Google Sites, How can I connect to another user spreadsheet using username and password, alike one usually does with mysql?
I tried the following, but it did not work :
var opts = {dataType:'json',username:'xxxxx',password:'xxxxxx'};
var query = new google.visualization.Query(urlTable, opts);
yes i need to connect to a spreadsheet, who owner is other user(spreadsheet is in other account), from code JS with top two lines that i posted at the first post in this thread
using username and password that i have
i see this https://developers.google.com/gadgets/docs/oauth#examples but i dont understand well
thanks
The error in site is Access denied because the owner of document is other gmail account...

Categories