Ruby Geocoder for google business - ruby-on-rails

Im using the Geocoder gem for ruby. With V2 of the google maps API for business you could pass in your API key in config/initializers/geocoder.rb in V3 of the API they no longer give you an API key but rather a client-id which is basically a cryptographic key that you use to create a signature for the url. Since I cannot obtain an API Key I dont quite know how to do the latter. Has anyone ran into this problem? If so could you please point me in a direction other than googles documentation.

The following config should work(Replace with your own information):
# -*- encoding : utf-8 -*-
Geocoder.configure do |config|
config.lookup = :google_premier
config.api_key = [ 'GOOGLE_CRYPTO_KEY', 'GOOGLE_CLIENT_ID', 'GOOGLE_CHANNEL' ]
config.timeout = 10
config.units = :km
end

Related

How to Authenticate Google Vision/Cloud Using ENV Variable in Ruby on Rails

My app is hosted on Heroku, so I'm trying to figure out how to use the JSON Google Cloud provides (to authenticate) as an environment variable, but so far I can't get authenticated.
I've searched Google and Stack Overflow and the best leads I found were:
Google Vision API authentication on heroku
How to upload a json file with secret keys to Heroku
Both say they were able to get it to work, but they don't provide code that I've been able to get work. Can someone please help me? I know it's probably something stupid.
I'm currently just trying to test the service in my product model leveraging this sample code from Google. Mine looks like this:
def self.google_vision_labels
# Imports the Google Cloud client library
require "google/cloud/vision"
# Your Google Cloud Platform project ID
project_id = "foo"
# Instantiates a client
vision = Google::Cloud::Vision.new project: project_id
# The name of the image file to annotate
file_name = "http://images5.fanpop.com/image/photos/27800000/FOOTBALL-god-sport-27863176-2272-1704.jpg"
# Performs label detection on the image file
labels = vision.image(file_name).labels
puts "Labels:"
labels.each do |label|
puts label.description
end
end
I keep receiving this error,
RuntimeError: Could not load the default credentials. Browse to
https://developers.google.com/accounts/docs/application-default-credentials for more information
Based on what I've read, I tried placing the JSON contents in secrets.yml (I'm using the Figaro gem) and then referring to it in a Google.yml file based on the answer in this SO question.
In application.yml, I put (I overwrote some contents in this post for security):
GOOGLE_APPLICATION_CREDENTIALS: {
"type": "service_account",
"project_id": "my_project",
"private_key_id": "2662293c6fca2f0ba784dca1b900acf51c59ee73",
"private_key": "-----BEGIN PRIVATE KEY-----\n #keycontents \n-----END PRIVATE KEY-----\n",
"client_email": "foo-labels#foo.iam.gserviceaccount.com",
"client_id": "100",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://accounts.google.com/o/oauth2/token",
"auth_provider_x509_cert_url":
"https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url":
"https://www.googleapis.com/robot/v1/metadata/x509/get-product-labels%40foo.iam.gserviceaccount.com"
}
and in config/google.yml, I put:
GOOGLE_APPLICATION_CREDENTIALS = ENV["GOOGLE_APPLICATION_CREDENTIALS"]
also, tried:
GOOGLE_APPLICATION_CREDENTIALS: ENV["GOOGLE_APPLICATION_CREDENTIALS"]
I have also tried changing these variable names in both files instead of GOOGLE_APPLICATION_CREDENTIALS with GOOGLE_CLOUD_KEYFILE_JSON and VISION_KEYFILE_JSON based on this Google page.
Can someone please, please help me understand what I'm doing wrong in referencing/creating the environmental variable with the JSON credentials? Thank you!
It's really annoying that Google decides to buck defacto credential standards by storing secrets via a file instead of a series of environment variables.
That said, my solution to this problem is to create a single .env variable GOOGLE_API_CREDS.
I paste the raw JSON blob into the .env then remove all newlines. Then in the application code I use JSON.parse(ENV.fetch('GOOGLE_API_CREDS') to convert the JSON blob into a real hash:
The .env file:
GOOGLE_API_CREDS={"type": "service_account","project_id": "your_app_name", ... }
Then in the application code (Google OCR client as an example):
Google::Cloud::Vision::ImageAnnotator.new(credentials: JSON.parse(ENV.fetch('GOOGLE_API_CREDS'))
Cheers
Building on Dylan's answer, I found that I needed to use an extra line to configure the credentials as follows:
Google::Cloud::Language.configure {|gcl| gcl.credentials = JSON.parse(ENV['GOOGLE_APP_CREDS'])}
because the .new(credentials: ...) method was not working for Google::Cloud::Language
had to look in the (sparse) ruby reference section of Google Cloud Language.
And yeah... storing secrets in a file is quite annoying, indeed.
I had the same problem with Google Cloud Speech, using the "Getting Started" doc from Google.
The above answers helped a great deal, coupled with updating my Google Speech Gem to V1 (https://googleapis.dev/ruby/google-cloud-speech-v1/latest/Google/Cloud/Speech/V1/Speech/Client.html)
I simply use a StringIO object so that Psych thinks that it's an actual file that I read:
google:
service: GCS
project: ''
bucket: ''
credentials: <%= StringIO.new(ENV['GOOGLE_CREDENTIALS']) %>

Invalid scope error

I'm trying to send bitcons using coinbase ruby gem but I'm having a hard time getting it to work. I'm authenticating like this:
c = Coinbase::Wallet::Client.new(api_key: ENV["COINBASE_KEY"], api_secret: ENV["COINBASE_SECRET"])
ca = c.account(User.last.account.account_id)
ca.send(to: ENV["BITCOIN_ADDRESS"], amount: '0.0001', currency: 'BTC')
This is the error I'm getting back.
Coinbase::Wallet::InvalidScopeError: Api::BaseController::InvalidScopeError
To be clear, the API key has the required permission set in the dashboard. what could i be doing wrong?
The new Ruby gem uses API v2 which requires v2 scope, wallet:transactions:send instead of v1's send. Can you check that you have this enabled?

How does Rails Geocoder Gem access Google API?

I know that we need to use a unique API key to access the Google Geocoding API.I am using the Rails Geocoder Gem in my application and found out that it uses the Google Geocoding API.I was unable to find any configuration files that define the API keys to access the Google API.How does the Geocoder gem access the Google API's.
Geocoder.configure(
:lookup => :google_premier,
:api_key => [ 'GOOGLE_CRYPTO_KEY', 'GOOGLE_CLIENT_ID', 'GOOGLE_CHANNEL' ],
:timeout => 5,
:units => :km,
)
https://github.com/alexreisner/geocoder
Here is one more link : http://hankstoever.com/posts/11-Pro-Tips-for-Using-Geocoder-with-Rails
under
Some common configuration options are:
You should look into this answer : Does Geocoder gem work with google API key?
It says:
Geocoder supports Google api keys for Google Premier accounts only.
But you can use the Client-Side framework to do that, instead of putting it on the server
https://developers.google.com/maps/articles/geocodestrat
I wrote something like that a few days back in ruby, if it helps :
require 'net/http'
require "resolv-replace.rb"
require 'json'
url = URI("https://maps.googleapis.com/maps/api/geocode/json")
puts "enter country code"
c_code = gets
puts "enter zip code "
zip = gets
url.query= URI.encode_www_form({ address: "#{c_code.chomp}+#{zip.chomp}" })
res = Net::HTTP::get_response(url)
json_data = res.body if res.is_a?(Net::HTTPSuccess)
data = JSON.parse(json_data)
p data

How do I setup geocoder with google_premier?

I've read the docs for the geocoder gem which state you can set a key, client and channel when using Google Premier.
According to some other posts I've read here, it's now possible to use an API key and still not pay as long as you're below the free threshold. We need to do this as we host with Heroku and we keep hitting our daily limit. We're not ourselves, but without any sort of other identification, we're probably reaching a limit identified by IP shared with other Heroku sites. Using a key will help identify us and therefore keep us from hitting a limit.
However, when I look at the sign up pages for the Google API, there are a baffling array of client ids, api keys and secrets, for installed apps, web apps and so on. Which combination is the one required to make geocoder burst into life?
To answer the question :
When subscribing to Google Premier, you should have received a client id starting by gme- and a key (see https://developers.google.com/maps/documentation/business/articles/prelaunch_checklist#welcome_letter)
The third argument needed by geocoder is the channel, that can be any kind of string (see https://developers.google.com/maps/documentation/business/guide#Channels )
You need to add the list of authorised urls originating the requests in the Google Portal (see https://developers.google.com/maps/documentation/business/guide#URLs ).
From the Geocoder doc, you can use a setting like :
# -*- encoding : utf-8 -*-
Geocoder.configure do |config|
config.lookup = :google_premier
config.api_key = ["gme-client-id","key", "channel"]
config.timeout = 10
config.units = :km
end
But it would probably be a better choice to use client-side geocoding like recommended here : https://developers.google.com/maps/articles/geocodestrat?hl=fr#client
This worked for me:
Geocoder.configure(
:lookup => :google_premier,
:api_key => [ 'GOOGLE_CRYPTO_KEY', 'GOOGLE_CLIENT_ID', 'GOOGLE_CHANNEL' ],
:timeout => 5,
:units => :km,
)
You'll need to substitute in the corresponding values from your Google Maps for Business welcome email. Channel is a value of your choosing.

Does Geocoder gem work with google API key?

I am using ruby geocoder gem for my project and as the project is growing I am starting to look into connecting to the Google API key. After adding this to the project:
Geocoder.configure do |config|
# geocoding service (see below for supported options):
config.lookup = :google
# to use an API key:
config.api_key = 'my_key'
# geocoding service request timeout, in seconds (default 3):
config.timeout = 5
end
I get Google Geocoding API error: request denied. when I start the application. From reading around, it seems like others switch over to yahoo if they choose to continue using the gem. Can I configure the gem to work with google api key? Mainly, I would like to keep an eye out for the amount of daily queries to avoid going over the limit.
Geocoder supports Google api keys for Google Premier accounts only.
Its found here in the readme on github: https://github.com/alexreisner/geocoder#google-google-google_premier
If you have a Google Premier api key you just need to put this in an intializer:
# config/initializers/geocoder.rb
Geocoder.configure(:lookup => :google_premier, :api_key => "...")
And your Geocoder will use your premier key.
I had this issue today and managed to solve it by setting use_https e.g.
Geocoder.configure(
timeout: 15,
api_key: "YOUR_KEY",
use_https: true
)
create a file: config/initializers/geocoder.rb and setup like this:
Geocoder.configure(
lookup: :google_premier,
api_key: ['api_key', 'client_id', 'client_id_type'],
)
Geocoder works fine with the free tier of their Map API. However, to make it work I had to register a key using this page specifically.
https://console.developers.google.com/flows/enableapi?apiid=geocoding_backend&keyType=SERVER_SIDE
And set up the configuration
# config/initializers/geocoder.rb
Geocoder.configure(
api_key: 'KEY_HERE',
use_https: true
)
By default Geocoder uses Google's geocoding API to fetch coordinates and street addresses. So, I think that a Google API key should work on the initializer.
I hope this work for you.
Geocoder.configure(
# geocoding service
lookup: :google,
# geocoding service request timeout (in seconds)
timeout: 3,
# default units
units: :km
)
This work for me. You can call API from rails console with geocoder doc at http://www.rubygeocoder.com/ than call it from view /my_map/show.html.erb replace address or city etc with <%= #place.address %>
If anyone is still looking at this, for some reason the Google API changed and Geocoder no longer works with the standard config file. However, you can simply not use the Geocoder gem for geocoding and reverse geocoding (don't use Geocoder.search) and use any http request gem to directly call the google api, as of this moment using RestClient the api call would be
response = RestClient.get 'https://maps.googleapis.com/maps/api/geocode/json?address=' + sanitized_query + '&key=' + your_key
where sanitized query can be either an address like Cupertino, CA or a lat=x, lng=y string for geocoding or reverse geocoding. It is not necessary to get a Google premier account.

Resources