HTTP Google Sheets API v4 how to access without OAuth 2.0? - bash

my idea is to create a google sheet, make it public and then access it from my work computer linux/bash to read/write values on a daily basis.
i have a public google doc sheet that anyone can find/edit.
this is the sheet ID: 1F6jh6756xNDlDYIvZm_3TrXb59EFEFHGEC7jdWz-Nx0
doing it by the book https://developers.google.com/sheets/api/samples/reading
curl 'https://sheets.googleapis.com/v4/spreadsheets/1F6jh6756xNDlDYIvZm_3TrXb59EFEFHGEC7jdWz-Nx0/values/Sheet1!A1:A3'
returns:
{
"error": {
"code": 403,
"message": "The request is missing a valid API key.",
"status": "PERMISSION_DENIED"
}
}
i've read a lot and especialy here Google Sheet API v4 i've found a complicated solution. that is if you want to access your public sheet in a short 1 hour period.
you browse to https://developers.google.com/oauthplayground/ get authorization for the v4 api, then get "Authorization code", then get "Refresh token", and finally "Access token".
using this "Access token" you can access the public sheet like this
curl 'https://sheets.googleapis.com/v4/spreadsheets/1F6jh6756xNDlDYIvZm_3TrXb59EFEFHGEC7jdWz-Nx0/values/Sheet1!A1:A3' -H "Authorization: Bearer ya29.GlvaBLjrTdsSuSllr3u2nAiC-BOsjvIOE1x5afU3xiafB-FTOdLWDtfabuIMGF1rId5BsZxiTXxrx7VDEtxww4Q1uvW9zRndkfm3I2LZnT1HK2nTWzX_6oXu-NAG"
returns:
{
"range": "Sheet1!A1:A3",
"majorDimension": "ROWS",
"values": [
[
"a1"
],
[
"a2"
],
[
"a3"
]
]
}
perfect. in theory the "Access token" expires after an hour, the "Refresh token" never expires. so you would save the tokens, try to read the sheet with the "Access token", if it fails use the "Refresh token" to gain a new "Access token" and carry on.
but, i've had a dozen of "Refresh token"s that were redeemed/expired, "Authorization code"s expired, all in all nothing works after a few hours. why?
how can i access my google sheet form bash with curl without this kind of authorization?
especially since my sheet is public and can be edited by anyone with a browser.
is there another way to do this with some other permanent authorization?
why not use email and pass?
"API key" is mentioned but never explained. can some one please explain this method step by step?

All Google APIs require that you create a project on Google developer console and identify yourself and your application, even to access public data. Since you have set the sheet to public you can just go to google developer console and create a public api key remember to active the google sheets api. Then just add key=[YourKey] as a parameter on your request.
Update Dev console:
Create project and get key:
Google developer console -> create a project -> credentials drop down -> API Key
Enable it:
Google developer console -> library find sheets enable it.
Update:
{ "error": { "code": 403, "message": "The request is missing a valid API key.", "status": "PERMISSION_DENIED" } }
Means that you have not identified yourself to Google. In 2015 Google Start to require that we identify ourselves you cant just use a Google API without telling google who you are. You do that by creating a project on [Google developer console1. Create an API key and use that API key in all of your requests. This only works with Public data.
https://sheets.googleapis.com/v4/spreadsheets/1F6jh6756xNDlDYIvZm_3TrXb59EFEFHGEC7jdWz-Nx0/values/Sheet1!A1:A3?key=YOurKEY
Note: With private user data you would need to use OAuth and use either access_token=your token or set the header
Authorization: Bearer ya29.GlvaBLjrTdsSuSllr3u2nAiC-BOsjvIOE1x5afU3xiafB-FTOdLWDtfabuIMGF1rId5BsZxiTXxrx7VDEtxww4Q1uvW9zRndkfm3I2LZnT1HK2nTWzX_6oXu-NAG.
An access token is not the same as a API Key.

If you don't want to mess with OAuth2, maybe the simpler solution is to use third-party soft. https://sheetdb.io allows you to work with Google spreadsheets and does OAuth2 for you. Additionally, the API is simpler than Google, check out the docs here: https://docs.sheetdb.io

Another approach is to share the sheet with a Google Cloud service account, and then use the service account to authorize with the API client. If the document is public you do not need to share it.
Instructions on creating a service account and reading a Google doc, which should also apply to sheets https://www.futurice.com/blog/read-goog-doc-using-service-account

A piece of advice - NEVER allow write access to a public Google Sheet.
Anyone can add lots of data and cause all sort of problems.
Always control access to who can edit.
Allow arbitrary edits by anyone programmatically is even worse. I can whip up a script that fill in your Google Sheet to capacity in seconds with garbage data. To everyone else viewing it, the sheet will look like a jumble of data.
Now to answer your question. Here are the basic steps for creating an OAuth 2.0 ClientID:
In the Google Cloud console, go to Menu menu > APIs & Services > Credentials.
Go to Credentials
Click Create Credentials > OAuth client ID.
Click Application type > Desktop app.
In the Name field, type a name for the credential. This name is only shown in the Google Cloud console.
Click Create. The OAuth client created screen appears, showing your new Client ID and Client secret.
Click OK. The newly created credential appears under OAuth 2.0 Client IDs.
Save the downloaded JSON file as credentials.json, and move the file to your working directory.
Follow the rest of the instructions for setting up the environment for a Go app to authenticate, authorize and manipulate the Google Sheet via Golang. For other languages, select the corresponding entry in the left sidebar of the web page.

Related

Google Sheet to Laravel 8 Integration

I want to integrate google sheet with Laravel 8 without any third party tool or connector. I know its simple for many but i am not able to get through. Highly appreciate for your effort and answers!
Requirements:
Google OAuth Keys.
Google Service Account.
Enabling Google Drive API and Google Sheets API.
revolution/laravel-google-sheets Laravel package.
Steps:
Step 1: Installing revolution/laravel-google-sheets package
composer require revolution/laravel-google-sheets
# publish package files
php artisan vendor:publish --provider="PulkitJalan\Google\GoogleServiceProvider" --tag="config"
Step 2: Setup Google API OAuth Key
Navigate to Google Developers Console
Create a Google project or select already existed project.
Click Create credentials followed by OAuth client ID.
If necessary, Configure consent screen.
Set the type to Web Application.
Copy client_id and client_secret and set in .env:
GOOGLE_CLIENT_ID=XXXXXX-XXXXXXXXXXXXXXXXXXXXXXXX.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=XXXXXX-XXXXXXXXXXX-XXXXXXXXXXXXXXXX
Step 3: Setup Google Service Account
Navigate to Google Developers Console
Create a new Service account key from Credentials.
Give your service account a name.
Under Grant this service account access to project step click on Select a Role dropdown and choose Project from left side and Editor from right side as shown in this image
Click Continue then Done.
Edit the service account and go to Keys tab.
Create a new Key of type JSON, and copy the json file to your project storage directory and rename it as credentials.json -or any other name you like.
Add credentials.json file path to .env as following
GOOGLE_SERVICE_ENABLED=true
GOOGLE_SERVICE_ACCOUNT_JSON_LOCATION=/home/user/code/project/storage/credentials.json
Step 4: Setup a Google Spreadsheet to integrate with
Create/Open a Google Spreadsheet file.
Give the sheet a name
Copy the ID of the document from file URL (e.g. https://docs.gogle.com/spreadsheets/d/{{SPREADSHEET_ID}}), see this image
Set the document id you copied in last step to .env
SPREADSHEET_ID=1kjtQBxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Copy the Email of the recently created Service Account, see this image
Share the sheet with the Service Account email as Editor, see this image
Step 5: Enable required Google APIs
Navigate to Google Developers Console APIs Dashboard.
Click ENABLE API AND SERVICES.
Search for Google Drive API and Enable it.
Search for Google Sheets API and Enable it.
Step 6: Test it
use Revolution\Google\Sheets\Facades\Sheets;
// Add new sheet to the configured google spreadsheet
Sheets::spreadsheet(config('sheets.spreadsheet_id'))->addSheet('sheetTitle');
$rows = [
['1', '2', '3'],
['4', '5', '6'],
['7', '8', '9'],
];
// Append multiple rows at once
Sheets::sheet('sheetTitle')->append($rows);
see the package documentation for more examples.
{ "error": { "code": 403, "message": "The request is missing a valid API key.", "errors": [ { "message": "The request is missing a valid API key.", "domain": "global", "reason": "forbidden" } ], "status": "PERMISSION_DENIED" } }
Dont forget to add scopes!
[\Google\Service\Sheets::DRIVE, \Google\Service\Sheets::SPREADSHEETS]
to the google.php config file

Can I move Google calendar events from one user to another user via API with a Service Account

I have created a Service account and I need to move event1 from calendar1 of User1 to calendar2 of User2.
When I request access token as User1 with "sub":"user1#gmail.com" during JWT step and using that token When I do following
POST https://www.googleapis.com/calendar/v3/calendars/User1calendarId/events/event1Id/move?Destination=user2calendarId
I get following error
{
"error": {
"errors": [
{
"domain": "calendar",
"reason": "requiredAccessLevel",
"message": "You need to have reader access to this calendar."
}
],
"code": 403,
"message": "You need to have reader access to this calendar."
}
}
Are there any permission that needs to be assigned to Service Account in order to make this operation? or What should be correct way to move event between different user's calendar as a Service Account?
Explanation:
The scopes you are adding to your application are classified as sensitive scopes, as they request access to private user data such as Calendar events.
Your application would need to undergo a verification process to be able to use these scopes. For more information, please check the official documentation.
Sensitive scopes
Some of the scopes used by the following APIs are considered sensitive; see the API documentation or look for the lock icon in the Cloud Console. If your app requests sensitive scopes, and doesn't meet any of the criteria for an exception (see below), you will need to verify that your app follows the API Services User Data Policy.
For a complete list of Google APIs, see OAuth 2.0 Scopes for Google APIs. To check if scopes are sensitive or restricted, add the scopes to your project via the Google Cloud Console.

How do i access my youtube brand account api? [duplicate]

I need to extract information from videos using YouTube Analytics and Reporting Api.
I have access to multiple YouTube Brand Accounts, when I log into YouTube with my Google Account.
Using the "Try it" for testing the API, I'm only able to retrieve data for a channel once I switch to the Brand Account that this channel belongs, otherwise I get 403 - Forbidden error.
Is there any way to extract data using the Google Account that I'm using to log in? Because once I create the credentials in developers console, they will be associated to the Google Account and not to the Brand Accounts.
My google account has Manager Role on the brand accounts.
I've search for the onBehalfOfContentOwner field to be used in requests, but I don't know how to get this ID, and I'm not sure if this is applicable in my situations, since we're talking about Brand Accounts, correct me if I'm wrong.
I fought with this just two days ago. Turns out it IS possible, it's just undocumented and works a bit differently than you'd expect:
Once I create the credentials in developers console, they will be associated to the Google Account and not to the Brand Accounts.
I had the same exact misconception when I first tried (even went so far as to find out the brand account's client_id). Turns out you don't want to use the brand's oauth info -- you want to use your own client_id/client_secret to create a refresh token on behalf of the brand account then use that to create auth tokens.
Steps:
Using your main account create an oauth client_id and client_secret via https://console.developers.google.com/apis/credentials
Edit the client_id/client_secret entry you just added and add "https://developers.google.com/oauthplayground" to the "Authorized redirect URIs" at the bottom of the page.
We're going to create a refresh token the lazy way. Go to https://developers.google.com/oauthplayground/
Click the gears on the top right corner and set access type to "offline", then click "Use your own OAuth credentials" and enter the client_id and client_secret you created in step 1.
Select the scopes you want to give it access to. Click authorize APIs.
Here's the magic bit: You'll now be asked to "Choose an account". Choose the brand account you want to access here, NOT your main account. Since you have permission to access it this'll work fine even though you're using your own client_id and client_secret
Allow the permission access when it prompts you, then you'll be brought back to the oauth playground.
Click "Exchange authorization code for tokens"
Grab the refresh token and use it like normal to generate auth tokens as needed.
Congratulations, you now have api access to the brand account!
Hope that helps.
The YouTube API is different then other google APIs. With other APIs you authenticate access to the full account. However with the YouTube API its channel based. You are going to need to authenticate your application once for each channel.
onBehalfOfContentOwner
This parameter is intended for YouTube content partners that own and
manage many different YouTube channels. It allows content owners to
authenticate once and get access to all their video and channel data,
without having to provide authentication credentials for each
individual channel. The actual CMS account that the user authenticates
with needs to be linked to the specified YouTube content owner.
You need to be a YouTube partner then you can contact your account manager and get a CMS id. I have yet to figure out what magic one must archive to become a YouTube partner.
I will give an update to #Paolo's incredible answer. In my case, I was trying to get my private videos using the Playlist.list api. I've never seen an api as poorly documented, asinine, and CONVOLUTED as youtube's api.
Context: I have a main google account for which my youtube api credentials are tied to (there is no google developer accounts for youtube brand accounts) but would like to get the private playlists (and videos) for my youtube account (a brand account). mine=true, key, channelId, onBehalfOfContentOwner, and onBehalfOfContentOwnerChannel all did NOTHING for me. I was getting either public playlists or api errors with various combinations and values of those parameters.
In the end, these were the steps I took to run a node script to get private videos from my brand account:
Go to https://console.developers.google.com/ for your main google account.
In the sidebar, go to APIs & Services, then Credentials
At the top, click +Create Credentials, then Service account
Under Service account details, enter any name, then click Create and Continue
Under "Grand this service account access to project", click continue
Under "Grant users access to this service account", click Done
On the main credentials page that loads, click the newly created service account under Service Accounts
In the tabs, click Keys
Click the Add Key button, then Create new key
Keep JSON, then click create
Save the file as client-key.json in the root of your nodejs project
Go to https://developers.google.com/oauthplayground
Scroll to bottom of scopes and select YouTube Data API v3 v3, then https://www.googleapis.com/auth/youtube and https://www.googleapis.com/auth/youtube.readonly.
In the window that pops up, click your youtube (brand) account, then allow
In the next step, click Exchange authorization code for tokens
Copy the access token
Go back to your node script and use like this:
const auth = new google.auth.GoogleAuth({
keyFile: "client-key.json",
scopes: [
"https://www.googleapis.com/auth/youtube",
"https://www.googleapis.com/auth/youtube.force-ssl",
"https://www.googleapis.com/auth/youtube.readonly",
"https://www.googleapis.com/auth/youtubepartner",
"https://www.googleapis.com/auth/youtubepartner-channel-audit",
],
})
const authClient = await auth.getClient()
google.options({ auth: authClient })
const youtube = google.youtube("v3")
const token = "your token here"
const results = await youtube.playlists.list({
part: [
"snippet",
"id",
"contentDetails",
"status",
"localizations",
"status",
],
mine: true,
auth: token,
oauth_token: token,
maxResults: 50,
})
Note mine: true and that the token must be passed to BOTH auth and oauth_token, but not key. If either parameter is missing, the call will fail. (Why? No clue. Please tell me.) Also, you must continuously renew your access token in the playground after it expires.
Now, with all of this said, I encourage you to find me an api worse than the youtube api. My guess is you'll be hard-pressed to find one even half as ridiculous as this.
P.S.
I believe there were additional things required before this such as enabling the youtube api and doing something on the OAUTH Consent Screen but I'm too exhausted with this thing to continue. Hopefully the Google console UX will be enough to guide you through those steps, though quite frankly, I doubt it.
Hope this helps and good luck, because you may actually need it.
If you follow the solution for getting a permanent refresh token and use Java, this works for me
GoogleCredential credential = new GoogleCredential.Builder().setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setClientSecrets(oauth2ClientId, oauth2ClientSecret)
.build()
.setRefreshToken(oauth2RefreshToken);
this.youTubeClient = new YouTube.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME)
.build();
Required dependencies
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-youtube</artifactId>
<version>v3-rev212-1.25.0</version>
</dependency>
<dependency>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-oauth2-http</artifactId>
<version>0.18.0</version>
</dependency>
These resources might also help once you have the refresh token:
Authenticate programmatically to Google with OAuth2
https://blog.timekit.io/google-oauth-invalid-grant-nightmare-and-how-to-fix-it-9f4efaf1da35

How do I create a Google Oauth2 client_id that doesn't just return "Forbidden"?

I'm trying to use p2/OAuth2 to access my documents on Google Drive.
I downloaded the sample Mac app and ran it, and it shows a Google "OAuth consent screen", and I click the "Allow" button, and it all works. So I think the sample code is good.
Then I logged into the Google APIs console, and:
enabled all the APIs that seemed like they might be relevant to this test (getting my name and user info): "Google Drive API", "Contacts API", "People API", "Google IAM API", etc.
created a "project" for my application
created a new "OAuth client ID" (credentials) for my app
I pasted my client_id into the OAuth2App sample, in place of the demo client_id/client_secret, and it fails. It shows the "OAuth consent screen" in a sheet, with the name of my application, but when I click "Allow", it just says "Forbidden".
Things I've tried that didn't help:
I've found this page which says creating a client ID of type "Other" in Google doesn't work, and I need to choose iOS. I've tried both "Other" and "iOS" types, and both give me "Forbidden".
With type "Other", it gives me a client_secret, as well. I don't want or need that, because this is a local app, but I found this question which suggests it doesn't matter to Google. I tried every way:
With the correct client_secret, I get "Forbidden".
With an incorrect client_secret, I get "Unauthorized".
With no client_secret, I get "client_secret is missing".
So I know it's checking that for type="Other", and doesn't seem to care that it's absent for type="iOS". In any event, since it's a different error when that's wrong/missing, that doesn't seem to be my problem here.
I turned on oauth.verbose to see if there's anything useful, but the logs are identical to the successful case (stock IDs), except for the values of some of the IDs/tokens.
How did p2/OAuth2 create a client_id for Google that works? Why is mine only returning "Forbidden"?
If it is your Local app, You'll need to select the installed option while selecting the type, and use Web Athorization Broker
this link might be helpful, its unsolved but has solution for the point you are stuck.
1.) ClientID and ClientSecret both are necessary while using installed application.
--> Also check your network rights if it is allowing the Drive api, that can also give Forbidden Error

Where can I get Google developer key

I am working on Google API like chat, contacts and so on...
I am stuck on developer_key as mentioned in gdata doc.
You can get this at https://code.google.com/apis/console:
'developer_key' => ''
I have already:
// OAuth2 Settings, you can get these keys at https://code.google.com/apis/console
'oauth2_client_id' => '',
'oauth2_client_secret' => '',
'oauth2_redirect_uri' => ''
Where can I find developer key?
I found some thing like this
http://code.google.com/apis/youtube/dashboard/gwt/index.html
But I understand this to be only for youtube.
It's the API key as listed under 'API Access', the 'Simple API Access' box.
First activate Google+ API, then you will get "Simple API access" box, from there you can get
developer key as API key
https://code.google.com/apis/console/?api=plus
or read this: http://code.google.com/p/google-api-php-client/wiki/OAuth2
Update Nov 2015:
Sometime in late 2015, the Google Developers Console interface was overhauled again. For the new interface:
Select your project from the toolbar.
Open the "Gallery" using hamburger menu icon on the left side of the toolbar and select 'API Manager'.
Click 'Credentials' in the left-hand navigation.
Alternatively, you can click 'Switch to old console' under the the three-dot menu (right side of the toolbar), then follow the instructions below.
For the NEW (edit: OLD) Google Developers Console:
You get your 'Developer key' (a.k.a. API key) on the same screen where you get your client ID/secret. (This is the 'Credentials' screen, which can be found under 'APIs & auth' in the left nav.)
Below your client ID keys, there is a section titled 'Public API access'. If there are no keys in this this section, click 'Create new Key'. Your developer key is the 'API key' specified here.
Update no 3:
You can get a Developer_Key from here Get your Google Developer Key
Check this tutorial
{select as answered, if it answered.}
Update no 2:
"API key" is the DEVELOPER_KEY
if you check this code reference,
it states
Set DEVELOPER_KEY to the "API key" value from the "Access" tab of the Google APIs Console http://code.google.com/apis/console#access`
Wiki on step by step to get API Key & secret
Update:
Developer API Key! probably this is what you might be looking for
http://code.garyjones.co.uk/google-developer-api-key
OR
If say, for instance, you have a web app which would require a API key then check this:
Go to Google API Console Select you project OR Create your project.
Select APIs & Auths
API Project from the Dropdown on the left navigation panel
API Access
Click on Create another Client ID
Select Service application refer it here
The Service application that you have created can be used by your Web apps such as PHP, Python, ..., etc.
2017 Update
Open Google API - https://console.developers.google.com
Go to Credentials.
Click on the 'Create Credentials' button. At time of writing it's currently a blue coloured dropdown.
Select API Key.
You should get a dialog from where you can copy this API key to use in your project. Hope this helps.
In the old console layout :
Select your project
Select menu item "API access"
Go to the section below "Create another client ID", called "Simple API Access"
Choose one of the following options, depending on what kind of app you're creating (server side languages should use the first option - JS should use the second) :
Key for server apps (with IP locking)
Key for browser apps (with referers)
In the new cloud console layout :
Select your project
Choose menu item "APIs & auth"
Choose menu item "Registered app"
Register an app of type "web application"
Choose one of the following options, depending on what kind of app you're creating (server side languages should use the first option - JS should use the second) :
Key for server apps (with IP locking)
Key for browser apps (with referers)
In case of both procedures, you find your client ID and client secret at the same page. If you're using a different client ID and client secret, replace it with the ones you find here.
During my first experiments today, I've succesfully used the "Key for server apps" as a developer key for connecting with the "contacts", "userinfo" and "analytics" API. I did this using the PHP client.
Wading through the Google API docs certainly is a pain in the #$$... I hope this info will be useful to anyone.
Please use Google API console
Create a new project
For the created project goto API access
There you will find your Client ID and Secret.
And the API key in the last is your developer key.
Recent Update July 2017:
Go to Google Console
Click on Left most top panel and click credentials.
In the API keys table, you will find the API key in the key column.
API Key is your developer key.
Hit https://www.googleapis.com/webfonts/v1/webfonts?key= in your browser by enabling web fonts api and you will see result.
Refer this blog http://code.garyjones.co.uk/google-developer-api-key/ for more information
I explored the google docs and found that developer key and api is same thing.
in https://code.google.com/apis/console/ , in SERVICES, turn on YOUTUBE API, then click API ACCESS in the left menu.
"Public API access" the key generated there is the key you got to paste into your public static final String DEVELOPER_KEY as part of this writing 26.12.2013
It is not the clientID but you got take the steps mentioned above to obtain one and generate the public api access key.
Go to https://code.google.com/p/google-api-php-client/wiki/OAuth2
Scroll down to where it says 'Visit the Google API Console to generate your developer key, OAuth2 client id, OAuth2 client secret, and register your OAuth2 redirect uri. Copy their values since your will need to input them in your application.'
Click on the 'Google API Console' link.
When it pops up and says 'Welcome to the new Google Developers Console! Prefer the old console? Go back | Dismiss' Click on 'GO BACK'
If you are only calling APIs that do not require user data, such as
the Google Custom Search API, then API keys might be simpler to use
than OAuth 2.0 access tokens. However, if your application already
uses an OAuth 2.0 access token, then there is no need to generate an
API key as well. Google ignores passed API keys if a passed OAuth 2.0
access token is already associated with the corresponding project.
Note: You must use either an OAuth 2.0 access token or an API key for
all requests to Google APIs represented in the Google Developers
Console. Not all APIs require authorized calls. To learn whether
authorization is required for a specific call, see your API
documentation.
Reference: https://developers.google.com/console/help/new/?hl=en_US#credentials-access-security-and-identity
tl;dr
Developer Key = Api Key (any of yours)
find it in Google Console -> Google API -> Credentials
You should be able to generate a Youtube API key there.
The recommended way to authorize your API call is to use OAuth 2.0 (without API key), as pointed by the documentation an API key is only necessary when using OAuth 1.0 credentials.
The API key for your application can be found in the Google APIs Console in API Access > Simple API.

Resources