Bonjour !
I have seen a lot of similar questions, but can't figure out why none of them brings a clear answer.
I'm trying to use the google-api-client gem to connect to youtube data api to retrieve a thumbnail image from a youtube video link.
I assume I don't need to deal with that (obscure to me) oAuth authentication.
First step : I create the project with google api console, authorizing the Youtube Data API. In the "API Access" tab, I select "Create a client ID..." with option "Service Account".
It gave me a client ID, email address and public key fingerprints.
Second : I create my ruby script using the google-api-client gem. I just copy/paste the example in the documentation that is :
require 'google/api_client'
client = Google::APIClient.new
From my client object I thought I could directly call
client.execute()
to get my atom feed with all my video information. But I just have an idea how to do it.
Maybe I also have to get oAuth authorization ? To get the token ?
What am I missing ?
Many thanks for your contributions.
That wasn't so hard, I found out how to do it.
You don't need to deal with oAuth authentication in that case. You will need to generate a server API Key and send it on each request.
The following snippet will help retrieving all information about a video the API provides.
require 'google/api_client'
require 'json'
client = Google::APIClient.new
youtube = client.discovered_api('youtube', 'v3')
client.authorization = nil
result = client.execute :key => "<YOUR_SERVER_API_KEY>", :api_method => youtube.videos.list, :parameters => {:id => '<YOUR_VIDEO_ID>', :part => 'snippet'}
result = JSON.parse(result.data.to_json)
Related
I've carefully reviewed Steve Bazyl's presentation at https://www.youtube.com/watch?v=iK14bfd6qhs and relevant API docs on google. I'm using the Service Account email id for my gmail account, and am using the private key downloaded from the Console.
But when I run the test client modeled after the one Steve showed in his presentation I consistently get
Signet::AuthorizationError:
Authorization failed. Server message:
{
"error" : "invalid_grant"
}
I get the same error message if I add garbage letters to the email or scope passed to JWTAsserter. Clearly something wrong but I can't seem to figure out how to troubleshoot this.
Here's the client code I'm running (in a rails rspec file):
client = Google::APIClient.new
key_file = '/Users/stu/projects/br/rails-app/######-privatekey.p12'
key = Google::APIClient::KeyUtils.load_from_pkcs12(key_file, 'notasecret')
Rails.logger.info "Private key? #{key.private?}"
asserter = Google::APIClient::JWTAsserter.new(
'#####-#######knp#developer.gserviceaccount.com',
"https://www.googleapis.com/auth/calendar",
key)
client.authorization = asserter.authorize()
I'm pretty well stuck, would definitely appreciate any troubleshooting advice.
Thanks!
Update
Thanks for sharing code that works for you Jack.
I've gone to my site's dev console and created a service account client p12 key. I then went to the site's Admin Console and added my client id granting site-wide authorization to the calendar API
In the Admin Console after adding the authorization it looks like this:
XXXXXXXXXXXhnq.apps.googleusercontent.com Calendar (Read-Write) https://www.googleapis.com/auth/calendar
I downloaded the p12 key and used it in the code structure you provided. I also tried with the approach from Steve Bazyl's presentation:
asserter = Google::APIClient::JWTAsserter.new(
"XXXXXXXXXXX-hnq#developer.gserviceaccount.com",
"https://www.googleapis.com/auth/calendar",
key)
client.authorization = asserter.authorize("stu#XXXXXXXXXX.com")
In both cases I get the same output as before:
Signet::AuthorizationError:
Authorization failed. Server message:
{
"error" : "invalid_grant"
}
I get that same output if I type in junk instead of "XXXXs://www.googleapis.com/auth/calendar". The key is valid, and while it's clear I'm doing something wrong, I can't find any clues in the API or google about how to tell what it is.
Any ideas how to troubleshoot?
Have you given service account access to your Google Apps account? You can find out how to that here: https://developers.google.com/+/domains/authentication/delegation#delegate_domain-wide_authority_to_your_service_account
Following code works for me:
key = Google::APIClient::KeyUtils.load_from_pkcs12('tmp/##########-privatekey.p12', 'notasecret')
client = Google::APIClient.new({:application_name => "example-app", :application_version => "1.0"})
client.authorization = Signet::OAuth2::Client.new(
:person => 'name#example.com',
:token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
:audience => 'https://accounts.google.com/o/oauth2/token',
:scope => 'https://www.googleapis.com/auth/drive.readonly',
:issuer => '123456789#developer.gserviceaccount.com',
:signing_key => key)
client.authorization.fetch_access_token!
drive = client.discovered_api('drive', 'v2')
result = client.execute(api_method: drive.files.list)
There is a long thread regarding this on GitHub which seems to indicate the problem is related to the system's date and time being "a little off." The suggested solution is to run sudo ntpdate ntp.ubuntu.com.
The thread is closed but it does have a link to this information from Google about "Invalid Grant".
Never was able to figure out how to get past the invalid_grant error.
My solution was to get a refresh token using the normal webapp api. Once retrieved it seems to be usable indefinitely so the end result appears to be the same.
I have tried various ruby codes to extract tweets, i came to know that in order to get tweets i have to create a twitter application and use Oauth for getting consumer key. My question here is can i not access the public tweets without using Oauth since i am working on a project where i have to analyze tweets.
The ruby code that i tried is as follows
require 'tweetstream'
require 'rubygems'
TweetStream.configure do |config|
config.username = 'twitterusername'
config.password = 'twitterpassword'
config.auth_method = :basic
end
#client = TweetStream::Client.new
#client.sample do |status|
puts "#{status.text}"
end
I get Failed to reconnect to twitter error.
There is no access to the twitter api with out Oauth. You will need to create a twitter application in order to request this information from the API.
You can start reading here: Authentication & Authorization
I started a web based dev project using YouTube and when I signed up for the API all I received was a client ID and email ID. However in the Ruby example text for calling the data API it states:
def initialize(scope)
credentials = Google::APIClient::ClientSecrets.load
#authorization = Signet::OAuth2::Client.new(
:authorization_uri => credentials.authorization_uri,
:token_credential_uri => credentials.token_credential_uri,
:client_id => credentials.client_id,
:client_secret => credentials.client_secret,
:redirect_uri => credentials.redirect_uris.first,
:scope => scope
I don't know where to go to grab these credentials. Ideas?
Since YouTube is now Google-account-based, these credentials need to be acquired on the Google Developers Console (pick the YouTube Data API), and you'll have to initiate the normal Google sign-in process. Your client_id and client_secret are generated when you create a new application on the console, your redirect_uri is set based on your application structure.
While Signet has a nice OAuth2 module associated with it, I've found Omniauth to be very easy to work with (and you can still use it in conjunction with Signet). If you don't need to customize the sign in process, Omniauth puts most of this in a black box (it's very high-touch), and handles token refreshes, etc. for you. I might use the Omniauth Google strategy to get your tokens, then the Google Ruby client to make requests.
i am using google api for ruby, but not know how to start, just give me an ABC example someone, thanks very much?
If you are creating a Service Account application to access Google Analytics.
Register it with Google through https://code.google.com/apis/console.
On API Access tab, click Create client ID, choose Service Account. Store the key file Google will generate, and remember the password for that key.
Here is some code to get you started
require 'rubygems'
require 'google/api_client'
api_client = Google::APIClient.new
path_to_key_file ="/path/to/key/file-privatekey.p12"
passphrase = "google_generated_password"
key = Google::APIClient::PKCS12.load_key(path_to_key_file, passphrase)
Once a key is available, initialize the asserter with your client ID (email in APIs console)
and authorization scopes.
asserter = Google::APIClient::JWTAsserter.new(
'super_long_client_id_from_api_console#developer.gserviceaccount.com',
'https://www.googleapis.com/auth/analytics.readonly',
key)
# To request an access token, call authorize:
api_client.authorization = asserter.authorize()
puts api_client.authorization.access_token
http://code.google.com/p/google-api-ruby-client/wiki/ServiceAccounts
I've answered something similar in a couple of other posts I found that were like this one... so incase its relevant, for ruby, using the google-api-client (for any of the google apis), there's a few ins and outs with authentication when using an api key as opposed to OAuth...
I've outlined this process (using an api key server side) at the code abode.
You have to explicitly set the authorzation param to nil when constructing the client, otherwise the gem tries to use OAuth to authenticate, so if calling from a server using an api key only, you will always get a 401 Unauthorized.
the code abode - google-api-client for ruby
I'm trying the following sample code, and failing (the uid and password I'm using are valid). Is there something I'm missing, or a simpler example I can try?
testing.rb:
require('rubygems')
gem('twitter4r','>=0.2.0')
require('twitter')
client = Twitter::Client.new(:login => 'uid', :password => 'password')
ARGV.each do |a|
#message = "#{a}"
end
status = client.status(:post, #message)
prompt> ruby testing.rb "test"
/Library/Ruby/Gems/1.8/gems/twitter4r-0.6.0/lib/twitter/client/base.rb:120:in
`raise_rest_error': Unauthorized
(Twitter::UnauthorizedError) from
/Library/Ruby/Gems/1.8/gems/twitter4r-0.6.0/lib/twitter/client/base.rb:125:in
`handle_rest_response' from
/Library/Ruby/Gems/1.8/gems/twitter4r-0.6.0/lib/twitter/client/base.rb:23:in `rest_oauth_connect' from
/Library/Ruby/Gems/1.8/gems/twitter4r-0.6.0/lib/twitter/client/status.rb:42:in `status' from testing.rb:11
#blueberryfields you will need to use the OAuth API that Twitter4R v0.5.0+ supports. This is due to Twitter.com mandating OAuth authentication as of August 2010. Supplying the login and password of your username is no longer supported either via Twitter4R, twitter.com or any other Twitter API client.
There is a fantastic tutorial on using OAuth with Twitter4R at this blog:
http://blog.monnet-usa.com/?p=342
HTH,
#SusanPotter -- Author of Twitter4R
PS Also check out #t4ruby for updates to Twitter4R
Twitter doesn't allow basic Auth (username+password) logins through their API anymore.
You should look for a method that supports OAuth-based login.
You'll need to fetch OAuth keys for your application, which can be done from the following links. The first link allows you to enroll a new application, the second one allows you to see what applications you've registered.
New Twitter Application # dev.twitter.com
Twitter Applications (Existing) # dev.twitter.com
A more in-depth guide is available at the following link. You will want to read this as OAuth requires at least two steps to authenticate before you can use the twitter API.
Authenticating Requests with OAuth