google-api-ruby-client
I am trying to update
and delete
videos using the YouTube API v3 with OAuth2 for authentication via the google-api-client (0.6.4)
Ruby gem. However, when I attempt to execute either of these two actions, I see the following error message:
Google::APIClient::ClientError: Insufficient Permission
Here's the odd thing: Using the exact same authentication procedure as with update
and delete
, I can insert
(upload) successfully, no problem! So, I do not believe this is a problem with my authentication setup, but somewhere else in my code.
My read-write scope
is always the same across any of these actions:
https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtube.upload
And according to the API documentation, that space-delimited set of scopes should cover insert
, update
and delete
actions.
My client_id
, client_secret
, refresh_token
are always the same for all these actions too -- so, that can't be the problem either, can it? Note that my program automatically obtains a new access_token
when it expires, so, again, I do not believe that is where the problem lies.
To compare, here is what my insert
(upload) code looks like (this works):
# Auth stuff, then...
@client.execute!(
:api_method => @youtube.videos.insert,
:body_object => body,
:media => Google::APIClient::UploadIO.new(file_path, 'video/*'),
:parameters => {
'uploadType' => 'multipart',
:part => body.keys.join(','),
}
)
And here is what my delete
code looks like (this fails):
# Auth stuff, then...
@client.execute!(
:api_method => @youtube.videos.delete,
:parameters => {
'id' => youtube_id,
}
)
What am I missing? Unfortunately, the YouTube API documentation for delete does not provide any examples, so I've got nothing to compare against. Please let me know if there is further information that I can provide to make my question clearer.
Source: (StackOverflow)
This is my code:
@token = @auth["credentials"]["token"]
client = Google::APIClient.new
client.authorization.access_token = @token
service = client.discovered_api('calendar', 'v3')
@result = client.execute(
:api_method => service.calendar_list.list,
:parameters => {},
:headers => {'Content-Type' => 'application/json'})
My question is: Where can I find a list of :api_method for Google calendar API?
Source: (StackOverflow)
I am trying to mock some methods that use the google-api-ruby-client to make some testing without actually calling the api. Authentication and client and activities methods are taken from the example found on the github page (see link above), which is why I skipped it here.
The method from the example is the following:
def activities
result = client.execute(
:api_method => plus.activities.list,
:parameters => {'collection' => 'public', 'userId' => 'me'}
)
return result.data
end
I previously tried to stub the client (even chained with the execute) methods, however this results in authorization requests for oauth, which the gem uses underneath followed by mocks for the plus.activities.list methods. Is there a way to directly mock client.exectute to return something useful while skipping the whole chain?
Source: (StackOverflow)
I am currently using the google-api-ruby-client to upload videos to Youtube API V3, but I can't find a way of getting the Youtube ID that is created by a resumable upload. The code I am trying to use is along the lines of:
media = Google::APIClient::UploadIO.new(file_path, 'application/octet-stream')
yt_response = @client.execute!({
:api_method => @youtube.videos.insert,
:parameters => {
:part => 'snippet,status',
'uploadType' => 'resumable'
},
:body_object => file_details,
:media => media
})
return JSON.parse(yt_response.response.body)
But unfortunately for resumable uploads, yt_response.response.body
is blank. If I change the 'uploadType'
to 'multipart'
then body is a JSON blob that contains the Youtube ID. The response for a resumable upload though is only the resumable session URI for the upload with an empty body. How do I go from that URI into the Youtube ID I just created?
Source: (StackOverflow)
I have a Ruby app in development that uses the Google API (custom search engine). It's been working great with the Public API access key.
I just upgraded my internet to Uverse and suddently the Google API stopped working. I figured out the issue was the IP address. My Uverse modem uses IPv6.
Unfortunately, Google Developer Public API access keys seem to only accept IPv4 addresses so when I try to add my IPv6 address I get the error message: "The IP address is invalid".
Has anyone been able to get this to work? I would prefer not to implement oAuth if I can avoid it.
Source: (StackOverflow)
This might be a really stupid question, but how do you determine the parameters to pass in the client "discovered_api" call? and then what is the executed "api_method"
For instance, I'm trying to call the Admin SDK Users List call which is "GET https://www.googleapis.com/admin/directory/v1/users".
There doesn't seem to be a clear way of extracting this from the API reference, or am I just looking in the wrong place?
Source: (StackOverflow)
Tough time inserting an activity to google plus stream. After referring google developers guide.
I found an example for java - https://developers.google.com/+/domains/posts/creating
Is there a similar example to execute the activites.insert
query using google-api-ruby-client.
I followed following steps:
Define access to app via omniauth-google-oauth2
GOOGLE_CONSUMER_KEY = google_config['KEY']
GOOGLE_CONSUMER_SECRET = google_config['SECRET']
google_scope = "userinfo.email,
userinfo.profile,
plus.login,
plus.me,
plus.media.upload,
plus.profiles.read,
plus.stream.read,
plus.stream.write,
plus.circles.read,
plus.circles.write"
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, GOOGLE_CONSUMER_KEY, GOOGLE_CONSUMER_SECRET,
{
name: 'google',
scope: google_scope,
prompt: 'consent'
}
end
Use the token and refresh token to execute api calls google-api-ruby-client. Am able to list the activities using "plus", but to insert an activity I should use plusDomains.
client = Google::APIClient.new(:application_name =>'Demo GooglePlus',:application_version => '1.0.0')
plus = client.discovered_api('plus')
plusd = client.discovered_api('plusDomain')
client_secrets = Google::APIClient::ClientSecrets.load
auth=client_secrets.to_authorization
auth.update_token!(access_token: 'aRandomToken', refresh_token: 'aRandomRefreshToken')
result = client.execute(:api_method => plus.activities.list,:parameters => {'collection' => 'public', 'userId' => 'me'}, :authorization => auth)
>> This works, returns the list of activities
Using plus Domain
result = client.execute(:api_method => plusd.activities.insert,:parameters => {'collection' => 'public', 'userId' => 'me'}, :authorization => auth)
>> Returns 403 Forbidden
Later I realized that google api requires domain wide delegaton to use the domains api(I think thats correct?)
https://developers.google.com/+/domains
https://developers.google.com/+/domains/getting-started#accessing_the_apis - Will the oauth used in Step 1 above would suffice ?
https://developers.google.com/+/domains/quickstart/python - Is there anything available in RUBY
I tried the service account setup also, created a business app and followed a service_account example
But still not luck.
Trying on terminal
curl -v -H "Content-Type: application/json" -H "Authorization: OAuth ya12.AqwqwwAS1212grcECQ3iVAlg" -d "{'object':{'content':'Test message'},'access':{'items':[{'type' : 'domain'}],'domainRestricted':true}}" -X POST https://www.googleapis.com/plus/v1domains/people/me/activities
Results in ->
{
"error": {
"errors": [
{
"domain": "global",
"reason": "forbidden",
"message": "Forbidden"
}
],
"code": 403,
"message": "Forbidden"
}
}
May I get some help in inserting an activity on google plus user steam ?
Thanks!
Source: (StackOverflow)
I've been trying a few combinations but can't seem to come up with something that works. More information about the API I'm asking about can be found here https://developers.google.com/admin-sdk/directory/v1/reference/users/insert . I have a feeling I'm just not setting up the request correctly. The following bit of code is known to work. I use it to set up the client that is able to query all the users.
client = Google::APIClient.new(:application_name => "myapp", :version => "v0.0.0")
client.authorization = Signet::OAuth2::Client.new(
:token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
:audience => 'https://accounts.google.com/o/oauth2/token',
:scope => "https://www.googleapis.com/auth/admin.directory.user",
:issuer => issuer,
:signing_key => key,
:person => user + "@" + domain)
client.authorization.fetch_access_token!
api = client.discovered_api("admin", "directory_v1")
When I try to use the following code
parameters = Hash.new
parameters["password"] = "ThisIsAPassword"
parameters["primaryEmail"] = "tstacct2@" + domain
parameters["name"] = {"givenName" => "Test", "familyName" => "Account2"}
parameters[:api_method] = api.users.insert
response = client.execute(parameters)
I always get back the same error "code": 400, "message": "Invalid Given/Family Name: FamilyName"
I've observed a few things while looking into this particular API. If I print out the parameters for both the list and the insert functions e.g
puts "--- Users List ---"
puts api.users.list.parameters
puts "--- Users Insert ---"
puts api.users.insert.parameters
Only the List actually displays the parameters
--- Users List ---
customer
domain
maxResults
orderBy
pageToken
query
showDeleted
sortOrder
--- Users Insert ---
This leaves me wondering if the ruby client is unable to retrieve the api and therefore unable to submit the request correctly or if I'm just doing something completely wrong.
I'd appreciate any idea's or direction that might help set me on the right path.
Thank you,
James
Source: (StackOverflow)
I am trying to get activeVisitors with the google-api-ruby-client. The client is listed in the real time google analytics API docs here however I see nothing in the docs about using it for real time api.
I see the function discovered_api however I see no list for posisble parameters for the API name.
Example for Regular Analytics API:
# Get the analytics API
analytics = client.discovered_api('analytics','v3')
Does anyone know how to use this client to get real time active visitors?
Here is the code I am trying to use:
require 'google/api_client'
require 'date'
# Update these to match your own apps credentials
service_account_email = 'xxxxxxxxxxxxx@developer.gserviceaccount.com' # Email of service account
key_file = '/path/to/key/privatekey.p12' # File containing your private key
key_secret = 'notasecret' # Password to unlock private key
profileID = '111111111' # Analytics profile ID.
# Get the Google API client
client = Google::APIClient.new(:application_name => '[YOUR APPLICATION NAME]',
:application_version => '0.01')
# Load your credentials for the service account
key = Google::APIClient::KeyUtils.load_from_pkcs12(key_file, key_secret)
client.authorization = Signet::OAuth2::Client.new(
:token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
:audience => 'https://accounts.google.com/o/oauth2/token',
:scope => 'https://www.googleapis.com/auth/analytics.readonly',
:issuer => service_account_email,
:signing_key => key)
# Start the scheduler
SCHEDULER.every '1m', :first_in => 0 do
# Request a token for our service account
client.authorization.fetch_access_token!
# Get the analytics API
analytics = client.discovered_api('analytics','v3')
# Execute the query
visitCount = client.execute(:api_method => analytics.data.ga.get, :parameters => {
'ids' => "ga:" + profileID,
'metrics' => "ga:activeVisitors",
})
# Update the dashboard
send_event('current_visitors', { current: visitCount.data.rows[0][0] })
end
Error returned:
Missing required parameters: end-date, start-date.
Source: (StackOverflow)
I'm using the Google Drive API for ruby, and I'm trying to insert a file into an user drive. I can insert the file with success, but then, when I try to get the file Self Link, this is the URL returned https://www.googleapis.com/drive/v2/files/1PxrbKaO2xwOonUO0TB0FO3pkZDnSmRKTvIUmXw0vL6w, that says that i have exceeded the number of unauthenticated requests.
Well, I'm pretty sure I'm authenticated, because I followed all the tutorials and the code is almost the same.
Anyone knows why is this happening? why can I insert the file, but can't view it's Self Link?
Here is the code of the creation of a document in the drive, after the user allows the app with offline access:
SCOPES = [
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile'
]
class DriveAuthenticator
def self.create_document(user, title, description, parent_title, user_array)
client = DriveAuthenticator.initiate_client
if user.google_id.present?
if DriveAuthenticator.authenticate_client client, user
parent_id = get_parent_id client, parent_title
file_data = insert_empty_file client, title, description, DOCUMENT_MIME_TYPE, parent_id
return file_data.selfLink
end
end
end
private
def self.initiate_client
client = Google::APIClient.new(:application_name => 'stuff_app')
credentials = Google::APIClient::ClientSecrets.load
client.authorization.client_id = credentials.client_id
client.authorization.client_secret = credentials.client_secret
client.authorization.redirect_uri = credentials.redirect_uris.first
client.authorization.scope = SCOPES
client
end
private
def self.get_token_by_refresh_token(client, refresh_token)
client.authorization.refresh_token = refresh_token
client.authorization.grant_type = 'refresh_token'
client.authorization.fetch_access_token!
end
private
def self.insert_empty_file(client, title, description, mime_type, parent_id)
drive = client.discovered_api('drive', 'v2')
file = create_file_schema drive, title, description, mime_type, parent_id
result = client.execute(
:api_method => drive.files.insert,
:body_object => file)
if result.status == 200
result.data
else
puts "An error occurred: #{result.data['error']['message']}"
nil
end
end
private
def self.create_file_schema(drive, title, description, mime_type, parent_id)
file = drive.files.insert.request_schema.new({
'title' => title,
'description' => description,
'mimeType' => mime_type
})
file.parents = [{'id' => parent_id}]
file
end
end
Source: (StackOverflow)
My rails app will allow to create appointments. These appointments should then be exported to each users' google calendar.
I have installed omniauth-google-oauth2, and got my api key, client_id and client_secret for a Web application from Google's API Console.
I can authenticate users with omniauth, and store the access_token, refresh_token and expires_at date into my database, for later use.
When the time comes to export events to each users' google calendar (done in a background job) I get a response of Invalid Credentials.
What am I doing wrong?
Note: I can access user calender immediately after he authorizes in oauth, but not after some time passes.
Code:
sessions_controller
/auth/:provider/callback routes to this method:
auth = request.env["omniauth.auth"]
# Save token of user
current_user.google_auth_token = auth["credentials"]["token"]
current_user.google_auth_refresh_token = auth["credentials"]["refresh_token"]
current_user.google_auth_expires_at = Time.at auth["credentials"]["expires_at"]
current_user.save
omniauth config
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, ENV["GOOGLE_CLIENT_ID"], ENV["GOOGLE_CLIENT_SECRET"], {
access_type: 'offline',
scope: 'userinfo.email,calendar'
}
end
getting access to create users calendars
client = Google::APIClient.new
client.authorization.refresh_token = app.carer.google_auth_refresh_token
client.authorization.access_token = app.carer.google_auth_token
if client.authorization.refresh_token && client.authorization.expired?
client.authorization.fetch_access_token!
end
service = client.discovered_api('calendar', 'v3')
result = client.execute(:api_method => service.calendar_list.list)
# results in auth error, Invalid Credentials ...
Source: (StackOverflow)
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?
Source: (StackOverflow)
I am using google_drive gem that depends on google-api-client and the gem versions are:
google_drive (1.0.1)
google-api-client (0.7.1)
faraday (0.8.9)
faraday_middleware (0.9.0)
Now, on using GoogleDrive:
session = GoogleDrive.login_with_oauth('access_token')
I am getting the following exception:
NameError: uninitialized constant Faraday::FlatParamsEncoder
from /Users/Admin/.rvm/gems/ruby-1.9.3-p551@############/gems/google-api-client-0.7.1/lib/google/api_client.rb:118:in `block in initialize'
Checked the code for the version of the google-api-client that I am using, here:
https://github.com/google/google-api-ruby-client/blob/google-api-client-0.7.1/lib/google/api_client.rb
Couldn't find anything unusual.
Any help will be appreciated.
Thanks
Source: (StackOverflow)
I already have the login (OAuth) piece working with my app, what I am trying to do now is pull down the authenticated users' activity list (status feed, for example).
The user has the option to pull this list down after the fact of them being authenticated and here is my code, thus far:
# User Model
def gplus
auth = authorizations.find_by_provider("gplus")
client = Google::APIClient.new(application_name: "AppName", application_version: '1.0', authorization: nil)
plus = client.discovered_api('plus', 'v1')
result = client.execute(
key: API["gplus"][Rails.env]["secret"],
api_method: plus.people.get,
parameters: { 'collection' => 'public', 'userId' => 'me' }
)
return result.data
end
Here is the problem I keep running into (from rails console)
#<Google::APIClient::Schema::Plus::V1::Person:0x3fe649ed04bc
DATA:{"error"=>{"errors"=>[{"domain"=>"usageLimits", "reason"=>"keyInvalid", "message"=>"Bad Request"}], "code"=>400, "message"=>"Bad Request"}}>
I am using the https://github.com/google/google-api-ruby-client... any reason why this won't work?
Source: (StackOverflow)
I have a service account and I am using the OAuth2 gem together with the Google API Ruby Client:
require 'oauth2'
require 'google/api_client'
My objective is to fetch an access token which allows access to a specific user’s account and no other. I think this is often achieved using the sub
parameter when using HTTP, but how do I do this using the Ruby client libraries above?
I can get an access token successfully and use it to access the drive v2 file list API. I always see a single "How to get started with Drive" document in the response and no other.
I suspect my attempt to impersonate a user has not succeeded. Basically I’m passing in an email address as a sub
option to the function below:
client = Google::APIClient.new(...)
access_token = OAuth2::AccessToken.new(oauth2_client, client.authorization.access_token, {‘sub’ => ‘user@domain.com’} )
Presumably that isn’t the way to do this.
How to I retrieve an access token which is scoped to permit access impersonating a single user and no other?
Following Steve's comment I have dropped the intridea Gem and am now using Signet. I get a little further but I am stuck getting an access_denied error when I specify a :person. Without that I can authenticate but obviously I get access as the issuer.
require 'google/api_client'
...
client = Google::APIClient.new(:application_name => application_name, :application_version => application_version)
...
opts = {
:token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
:audience => 'https://accounts.google.com/o/oauth2/token',
:scope => scope,
:issuer => service_account_email_address,
:signing_key => key,
:person => 'my.email@address.com'
})
client.authorization = Signet::OAuth2::Client.new(opts)
access_token = client.authorization.fetch_access_token!
...
>> client.authorization.fetch_access_token!
Signet::AuthorizationError: Authorization failed. Server message:
{
"error" : "access_denied",
"error_description" : "Requested client not authorized."
}
I have a console project which I do a 'test install flow' on but the client does not seem to be trusted. Where do I look?
Thanks.
Source: (StackOverflow)