I am trying to use this Ruby Google Analytics API Dashing widget whose Ruby file is
require 'google/api_client'
require 'date'
# Update these to match your own apps credentials
service_account_email = '[YOUR SERVICE ACCOUNT EMAIL]' # Email of service account
key_file = 'path/to/your/keyfile.p12' # File containing your private key
key_secret = 'notasecret' # Password to unlock private key
profileID = '[YOUR PROFILE ID]' # 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')
# Start and end dates
startDate = DateTime.now.strftime("%Y-%m-01") # first day of current month
endDate = DateTime.now.strftime("%Y-%m-%d") # now
# Execute the query
visitCount = client.execute(:api_method => analytics.data.ga.get, :parameters => {
'ids' => "ga:" + profileID,
'start-date' => startDate,
'end-date' => endDate,
# 'dimensions' => "ga:month",
'metrics' => "ga:visitors",
# 'sort' => "ga:month"
})
# Update the dashboard
send_event('visitor_count', { current: visitCount.data.rows[0][0] })
end
However I am getting the error Undefined method '[]' for nil:NilClass for the second last line. Can anyone shed some light on what is going on here?
EDIT:
I now know that visitCount.data is an array of NIL objects. Are there any diagnostics I can perform to make sure that that the API is connecting correctly? Can anyone suggest a possible reason why this is happening?
Try this, before streaming the event
if visitCount.data.rows[0].empty?
# assign some default
output = -1
else
output = visitCount.data.rows[0][0]
end
# Update the dashboard
send_event('visitor_count', { current: output })
OK it turns out that I was given the incorrect profile ID. It's kind of surprising that there was no error saying something like "This profile ID does not exist". That would have been way more helpful. Anyways I have the correct profile ID now and it works. In case anyone was wondering, to find the profile ID, you navigate to the analytics profile that you are interested in and the end of the url has something like pXXXXXXXX where the X's are your profile ID.
Related
I would like to create Account object for Quickbooks. However, when I try:
service.create(account_object)
It returns the error:
Quickbooks::InvalidModelException: Classification is not included in the list
I tried putting in one of the default values(https://developer.intuit.com/docs/0025_quickbooksapi/0050_data_services/030_entity_services_reference/account), but it returns the same error..
Classification in account will be something like Liability, Revenue, Expense or Asset etc.
Go to this URL https://developer.intuit.com/docs/api/accounting/Account
look at AccountType section => Child attributes
It have all list of classification and account type that we can use while creating accounts
You can use below sample code to create account
begin
oauth_client = OAuth::AccessToken.new($qb_oauth_consumer, token, secret)
service = Quickbooks::Service::Account.new(:access_token => oauth_client, :company_id => realm_id)
new_account = Quickbooks::Model::Account.new(:name => 'Undeposited money', :account_type => 'Other Current Asset', :classification => 'Asset' )
create_acccount = service.create(new_account)
rescue Exception => e
# e.message will show response of quickbooks for you request
puts e.message
# e.message.inspect will show logs
puts e.backtrace.inspect
end
I've managed to fix the original issue below by removing the .readonly from the URL.
I'm now being presented with this error:
{"error"=>{"errors"=>[{"domain"=>"global", "reason"=>"notFound", "message"=>"Resource Not Found: domain"}], "code"=>404, "message"=>"Resource Not Found: domain"}}
Again, I've taken a look at this error online but all the links seem to go to an error page on Google and nothing to help determine a fix for this error.
Original Issue
I'm trying to use the below script to access to Google Directory API using Ruby but I'm receiving an error when I try to execute the script.
Script
#!/usr/bin/env ruby
require 'rubygems'
require 'json'
require 'google/api_client'
require 'active_support/core_ext/hash'
# The value of client_email from the JSON file goes here
SERVICE_ACCOUNT_EMAIL = 'xxxxxxxxx-bk7gbhr8k2dfvtidm0cc0msnipo34c8p#developer.gserviceaccount.com'
# This should be an Admin
ACT_ON_BEHALF_EMAIL = 'xxxxxx#gmail.com'
# File path to the certificate
SERVICE_ACCOUNT_PKCS12_FILE_PATH = '/home/xxxx/3ce8a60d43a8fa5cb747441fdfd90c3b91d6f45b-privatekey.p12'
key = Google::APIClient::PKCS12.load_key(SERVICE_ACCOUNT_PKCS12_FILE_PATH, 'notasecret')
asserter = Google::APIClient::JWTAsserter.new(SERVICE_ACCOUNT_EMAIL, 'https://www.googleapis.com/auth/admin.directory.user.readonly', key)
client = Google::APIClient.new(:application_name => 'GAAccountAudit')
client.authorization = asserter.authorize(ACT_ON_BEHALF_EMAIL)
api = client.discovered_api('admin', 'directory_v1')
result = client.execute(
:api_method => api.users.list,
:parameters => {
'domain' => 'http://www.xxxxxx.com',
'orderBy' => 'givenName',
'maxResults' => 500,
'fields' => 'users(id,etag,primaryEmail,name,suspended)',
}
)
users = JSON.parse(result.body, {:symbolize_names => true})[:users]
users.each do |u|
puts "#{u[:name][:fullName]} <#{u[:primaryEmail]}>"
end
Error
{"error" : "unauthorized_client","error_description" : "Unauthorized client or scope in request."}
I've read up on this error but I've not been able to find a conclusive answer to this. Could anyone please advise how I resolve this error?
I'm having an issue using the mandrill API for ruby and i'm not sure if it's a lack of ruby/api understanding on my part of if there's an issue with the mandrill api.
I have this method which sends an email with mandrill, and then I make another api call using the id returned from mandrill.messages.send to make another call to mandrill to get the email header message-id so i can store that in a db table.
Why am I getting the error Mandrill::UnknownMessageError (No message exists with the id '64fba1cce24942dea1ada4f905fd7871'): when the id clearly exists as seen in the comments for the logging events?
# Sends an email to all users for the account_id on the issue
def send_email
require 'mandrill'
...
mandrill = Mandrill::API.new Mandrill::API_KEY
# Email contents
message = {
:subject => self.name,
:from_name => self.account.subdomain,
:text => self.description,
:to => [{
:email => user.email,
:name => user.name
}],
:text => self.description,
:from_email => "noreply#myapp.com",
:headers => {
'reply-to' => 'update#myapp.com'
}
}
results = mandrill.messages.send message # Send email through mandrill
# Loop through results of sent email
results.each do |result|
logger.debug "result id = #{result['_id']}" # LOGS result id = 64fba1cce24942dea1ada4f905fd7871
logger.debug "result = #{result}" # LOGS result = {"email"=>"tomcaflisch#gmail.com", "status"=>"sent", "_id"=>"64fba1cce24942dea1ada4f905fd7871", "reject_reason"=>nil}
id = result['_id'] # Mandrill's internal id from api call results that sent the email
# CAUSES Mandrill::UnknownMessageError (No message exists with the id '64fba1cce24942dea1ada4f905fd7871'):
info = mandrill.messages.content id # Get info for sent email with a specific mandrill id
end
end
I think you just have to give it a little bit of time.
I am facing the same error on messages.info(id).
However, search('*') is finding all messages sent but not providing correct status information.
I think the following snippet of gem code is getting 500 status (instead of 200) when messages.info(id) is called:
def call(url, params={})
params[:key] = #apikey
params = JSON.generate(params)
r = #session.post(:path => "#{#path}#{url}.json", :headers => {'Content-Type' => 'application/json'}, :body => params)
cast_error(r.body) if r.status != 200
return JSON.parse(r.body)
end
Also, gem code is hosted on bitbucket instead of more common github. Not sure how to raise an issue there for support.
Sorry can't be of much help but thought I should share my experience also to get more visibility for the problem.
I'm trying to run a Query against Google Big Query, using the Ruby API.
This is my first project with Ruby and I'm still learning the language.
This is also my first project using the Google API.
ENVIORNMENT:
Windows 7
Ruby 1.9
Faraday 0.90
Goolge API - Service Account Authentication
My Code runs without giving any warnings or error messages through:
#client.authorization.fetch_access_token!
doc = File.read('bigQueryAPI.json')
#bigQuery = #client.register_discovery_document('bigquery', 'v2', doc)
NOTE: #bigQuery is loaded from a file because when I try to load #bigquery with
#bigquery = #client.discovered_api('bigquery', 'v2')
I get Google::APIClient::ClientError: Not Found and inspect only prints
#<Google::APIClient::API:0x17c94cc ID:bigquery:v2>
However If I save the Big Query API as a text file from
https://www.googleapis.com/discovery/v1/apis/bigquery/v2/rest
and then load it as a text file with
doc = File.read('bigQueryAPI.json')
#bigQuery = #client.register_discovery_document('bigquery', 'v2', doc)
then #bigQuery.inspect actually returns something useful.
#bigQuery.inspect output.
However, When I try to actually run a query, like so:
result = #client.execute!(
:api_method => #bigQuery.batch_path.query,
:body_object => { "query" => "SELECT count(DISTINCT repository_name) as repository_total, " +
"count(payload_commit) as commits_total, " +
"count(DISTINCT repository_name) / count(payload_commit) as average, " +
"FROM [githubarchive:github.timeline]" }, #,
:parameters => { "projectId" => #project_id })
I get the following error:
NoMethodError: undefined method `query_values' for nil:NilClass
Here's the Full Stacktrace of the error:
1) Error:
test_averages(Test_GitHub_Archive):
NoMethodError: undefined method `query_values' for nil:NilClass
C:/Ruby193/lib/ruby/gems/1.9.1/gems/google-api-client-0.7.1/lib/google/api_client/request.rb:145:in `uri='
C:/Ruby193/lib/ruby/gems/1.9.1/gems/google-api-client-0.7.1/lib/google/api_client/request.rb:101:in `initialize'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/google-api-client-0.7.1/lib/google/api_client.rb:518:in `new'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/google-api-client-0.7.1/lib/google/api_client.rb:518:in `generate_request'
C:/Ruby193/lib/ruby/gems/1.9.1/gems/google-api-client-0.7.1/lib/google/api_client.rb:583:in `execute!'
C:/Users/tfburton/Documents/private/ProjectSuggestor/RubyStats/GitHub_Archive.rb:39:in `get_averages'
C:/Users/tfburton/Documents/private/ProjectSuggestor/RubyStats/TestSpec/test_GitHub_Archive.rb:26:in `test_averages'
Here is the results for #client.inspect
NOTE: I would have pasted here, but my post ended over the length limit.
After doing some digging. It looks like I'm not passing the proper #bigQuery prameter to get the query function.
Looking at the dump for #bigQuery.inspect I need to pass the method at line 751.
However I can't seem to figure out how to pass that method.
If you strip out the rest of the inspect output the "path" looks like this:
{ "resources => { "jobs" => { "methods" => { "query"
I've tried #bigQuery.Jobs.query and that results in an error stating that #bigQuery.Jobs doesn't exist.
So am I creating #bigQuery correctly?
Why doesn't #bigQuery.Jobs.query work?
Here's how I got it to work with the bigquery.jobs.query method, which is probably what you need.
I had to set OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE because otherwise the authorization process would fail miserably, but that might be specific to min Win7/MgitSys environment. In any case, this specific line is not safe in prod.
require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/installed_app'
require 'google/api_client/auth/file_storage'
require 'openssl'
require 'json'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
# Initialize the client.
client = Google::APIClient.new(
:application_name => 'Example Ruby application',
:application_version => '1.0.0'
)
CREDENTIAL_STORE_FILE = "#{$0}-oauth2.json"
file_storage = Google::APIClient::FileStorage.new(CREDENTIAL_STORE_FILE)
# Initialize Google+ API. Note this will make a request to the
# discovery service every time, so be sure to use serialization
# in your production code. Check the samples for more details.
#bigQuery = client.discovered_api('bigquery', 'v2')
# Load client secrets from your client_secrets.json.
client_secrets = Google::APIClient::ClientSecrets.load
file_storage = Google::APIClient::FileStorage.new(CREDENTIAL_STORE_FILE)
if file_storage.authorization.nil?
client_secrets = Google::APIClient::ClientSecrets.load
# The InstalledAppFlow is a helper class to handle the OAuth 2.0 installed
# application flow, which ties in with FileStorage to store credentials
# between runs.
flow = Google::APIClient::InstalledAppFlow.new(
:client_id => client_secrets.client_id,
:client_secret => client_secrets.client_secret,
:scope => ['https://www.googleapis.com/auth/cloud-platform','https://www.googleapis.com/auth/bigquery']
)
client.authorization = flow.authorize(file_storage)
else
client.authorization = file_storage.authorization
end
puts "authorized, requesting"
# Make an API call.
result = client.execute!(
:api_method => #bigQuery.jobs.query,
:body_object => { "query" => "SELECT count(DISTINCT repository_name) as repository_total, " +
"count(payload_commit) as commits_total, " +
"count(DISTINCT repository_name) / count(payload_commit) as average, " +
"FROM [githubarchive:github.timeline]" }, #,
:parameters => { "projectId" => "845227657643" })
puts JSON.dump result.data
I'm making a call by this code
require 'riot_api'
# Create Instace of the API
ra = RiotApi::API.new :api_key => 'MY_API', :region => 'na', :debug => true
# Search by Summoner name
summoner_details = ra.summoner.name('GoncyRlz')
And I got this response
#<Hashie::Rash id=31029929 name="GoncyRlz" profile_icon_id=7 revision_date=1375116256000 revision_date_str="07/29/2013 04:44 PM UTC" summoner_level=30>
I want to take that id and save it to a variable called summonerid. How can I take it?
You can just access the id as if it were a method on the object, i.e.
summonerid = summoner_details.id
Also see https://github.com/tcocca/rash