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.
Related
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?
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
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
I am using Rails + Garb Gem (Sija Branch) + omniauth-google-oauth2 Gem and I can successfully authenticate with the Google Analytics API and extract data that our app is generating when using a user login, e.g.:
Garb::Session.login('USERNAME', '<PASSWORD>')
I can then use Garb to connect to the Analytics Profile I want and pull the data from it and display some charts on a webpage. This all works fine.
However, I want to use oAuth2 to authenticate with Analytics which is why I had to install the Sija branch of the Garb Gem from Github (it supports oAuth2) and I also installed the omniauth-google-oauth2 Gem. Now in theory I should be able to authenticate using the following code:
Garb::Session.access_token = access_token # an instance of OAuth2::Client
It's at this point that it gets a little hazy for me and I would greatly appreciate some guidance. Here's how far I have gotten:
1) I created a Project in the Google API console and turned on Analytics API under Services
2) This provided me with a Client ID and Client Secret
3) I came across this code which I could populate with the ID and Secret above:
client = OAuth2::Client.new(
GOOGLE_CLIENT_ID,
GOOGLE_CLIENT_SECRET,
{
:site => 'https://accounts.google.com',
:authorize_url => '/o/oauth2/auth',
:token_url => '/o/oauth2/token'
})
4) Then there is the next bit of code:
response = OAuth2::AccessToken.new(
client,
STORED_TOKEN, {
refresh_token: STORED_REFRESH_TOKEN,
expires_at: STORED_EXPIRES_AT
})
5) and then in theory connect with:
Garb::Session.access_token = response
The problem I have is I don't have the token information in Point (4) above. It seems to me that with oAuth2 I need to do a "handshake" once and print out the return token values? Perhaps through Rails code which prints the values returned out and then paste the token values into a constant in the Rails app so that I can use them in the above code? I really am confused. As I mentioned earlier, the web app works fine using the user login authentication. All the web app is doing is authenticating with analytics, pulling down some data and drawing a chart. But I am stuck converting it over to oAuth2 as I just do not know how to get the Access Token that the Garb Gem is looking for. I should also note that this is not a public website with multiple users authenticating, this is a CMS website that is connecting to our own Analytics data.
I have seen some partial snippets of aspects of this but not a fully explained or working example. I would really appreciate any guidance and help with this question.
Many thanks in advance,
JR
I've soldiered through this over the last few weeks, so let me share what worked:
To use Oauth2 you need to get a 'refresh token' that you use to 're-authenticate' with google each time you make an API call. The steps for this are as follows:
1) Setup your account in the API console - https://code.google.com/apis/console/b/0/ (seems like you've done that well)
2) In your API account, make sure you have a redirect URI pointing back to your application:
http://some-url.com/auth/google_oauth2/callback
http://localhost:3000/auth/google_oauth2/callback
Note here that google won't let you call back to your local machine as 0.0.0.0:3000... so you'll need to use localhost explicitly
3) In your route file, tie that redirect url to an action in the controller where you're going to create the project or authentication
match '/auth/:provider/callback' => 'authentications#create'
The ':provider' simply lets you match on multiple types of oauth, but you could just put 'google_oauth2' there as well.
4) Now create that action in your controller
def create
auth = request.env["omniauth.auth"]
params = request.env["omniauth.params"]
project = Project.find(params['project_id'])
Authentication.create(:project_id => project.id, :provider => auth['provider'], :uid => auth['uid'], :access_token => auth['credentials']['refresh_token'])
flash[:notice] = "Authentication successful."
redirect_to owner_view_project_path(project)
end
5) The controller action should retrieve the relevant fields from the response object (details of response object here: https://github.com/zquestz/omniauth-google-oauth2) - in particular, you need to get the 'refresh_token' and save that to your project or authentication object - if you haven't added an 'access_token' attribute to the desired object, go do that now with a migration, then start saving the refresh token to that attribute
6) Now when you're ready to call that particular authentication and get API data for it, you can load up that object where you saved the access token, and use that to get a new session with the google API as follows:
#authentication = Authentications.find(params[:id])
client = OAuth2::Client.new GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET,
{
:site => 'https://accounts.google.com',
:authorize_url => "/o/oauth2/auth",
:token_url => "/o/oauth2/token",
}
response = OAuth2::AccessToken.from_hash(client, :refresh_token => #authentication.access_token).refresh!
Garb::Session.access_token = response
#profiles = Garb::Management::Profile.all
What this code did was create an OAuth2 access token (response) by specifying the client and then a refresh_token, then calling 'refresh!' to get a refreshed access token... then use that access token to establish your Garb session, then call down all the profiles for a given account using the Gard::Management::Profile.all
Hope this helps - let me know if you have questions!
Just a note on what worked for me in:
For steps 3, 4 & 5 I used cURL instead to retrieve the Access/Refresh token. Step 6 is then the same for me (using the Sija branch of the Garb Gem). So using cURL:
Using the details associated with your Google app POST the following using cURL:
curl --data "code=<APP_CODE>&redirect_uri=http://localhost:3000/oauth2callback&client_id=<CLIENT_ID>.apps.googleusercontent.com&scope=&client_secret=<CLIENT_SECRET>&grant_type=authorization_code" https://accounts.google.com/o/oauth2/token
The response takes the form:
{
"access_token" : "<ACCESS_TOKEN>",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "<REFRESH_TOKEN>"
}
which you can plug into the Garb Gem as per part 6.
The answer by #CamNorgate is valid.
If you don't have a "refresh_token" back from Omniauth on the callback make sure you are correctly initializing :google_oauth2
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, ENV["GOOGLE_CLIENT_ID"], ENV["GOOGLE_CLIENT_SECRET"],
{ :scope=>"https://www.google.com/m8/feeds, https://www.googleapis.com/auth/userinfo.email, https://www.googleapis.com/auth/userinfo.profile",
:approval_prompt=>"force", access_type="offline"
}
end
Make sure to include :approval_prompt=>"force", access_type="offline" in order for the refresh_token to be sent back. The refresh_token is only provided on the first authorization from the user.
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.