Reputation: 146
I'm getting the following error message when I try to do an OAuth2 connection to google.
.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/google-api-client-0.7.1/lib/google/api_client/auth/file_storage.rb:49:in `at': can't convert nil into an exact number (TypeError)
Looking at the source this is trying to read a cached credentials file and is failing to parse an attribute called issued_at.
I initially set up my app with the wrong port in the google developer console. Now I've updated the client_secrets.json but I'm continually getting this error.
My code is trying doing the calendar example from the google site, but converted to use the admin directory API, but it isn't getting beyond the auth step.
Where is this cached value coming from?
require 'rubygems'
require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/file_storage'
require 'sinatra'
require 'logger'
enable :sessions
CREDENTIAL_STORE_FILE = "client_secrets.json"
def logger; settings.logger end
def api_client; settings.api_client; end
def directory_api; settings.directory; end
def user_credentials
# Build a per-request oauth credential based on token stored in session
# which allows us to use a shared API client.
@authorization ||= (
auth = api_client.authorization.dup
auth.redirect_uri = to('/oauth2callback')
auth.update_token!(session)
auth
)
end
configure do
log_file = File.open('directory.log', 'a+')
log_file.sync = true
logger = Logger.new(log_file)
logger.level = Logger::DEBUG
client = Google::APIClient.new(
:application_name => 'Ruby Directory sample',
:application_version => '1.0.0')
puts "store file : #{CREDENTIAL_STORE_FILE}"
file_storage = Google::APIClient::FileStorage.new(CREDENTIAL_STORE_FILE)
if file_storage.authorization.nil?
client_secrets = Google::APIClient::ClientSecrets.load
client.authorization = client_secrets.to_authorization
client.authorization.scope = 'https://www.googleapis.com/auth/admin.directory.user'
else
client.authorization = file_storage.authorization
end
# Since we're saving the API definition to the settings, we're only retrieving
# it once (on server start) and saving it between requests.
# If this is still an issue, you could serialize the object and load it on
# subsequent runs.
directory = client.discovered_api('admin', "directory_v1")
set :logger, logger
set :api_client, client
set :directory, directory
end
before do
# Ensure user has authorized the app
unless user_credentials.access_token || request.path_info =~ /\A\/oauth2/
redirect to('/oauth2authorize')
end
end
after do
# Serialize the access/refresh token to the session and credential store.
session[:access_token] = user_credentials.access_token
session[:refresh_token] = user_credentials.refresh_token
session[:expires_in] = user_credentials.expires_in
session[:issued_at] = user_credentials.issued_at
file_storage = Google::APIClient::FileStorage.new(CREDENTIAL_STORE_FILE)
file_storage.write_credentials(user_credentials)
end
get '/oauth2authorize' do
# Request authorization
redirect user_credentials.authorization_uri.to_s, 303
end
get '/oauth2callback' do
# Exchange token
user_credentials.code = params[:code] if params[:code]
user_credentials.fetch_access_token!
redirect to('/')
end
get '/' do
result = api_client.execute(:api_method => directory.users.list)
# # Fetch list of events on the user's default calandar
# result = api_client.execute(:api_method => calendar_api.events.list,
# :parameters => {'calendarId' => 'primary'},
# :authorization => user_credentials)
[result.status, {'Content-Type' => 'application/json'}, result.data.to_json]
end
Upvotes: 0
Views: 1452
Reputation: 2918
Change the line to CREDENTIAL_STORE_FILE = "#{$0}-oauth2.json"
and then rename the json you downloaded from the Google dashboard to client_secrets.json
per convention. CREDENTIAL_STORE_FILE
is where your OAuth tokens get stored and is created by the FileStorage
instance.
Upvotes: 1