はじめに
個人開発をするにあたって、セレクトショップとカフェの情報を取得したかったので、GooglePlacesAPIを使用して取得することにしました。ただ、今回APIを使用するのが初めてで苦労したので、同じような状況の方のために、使い方を記録として残します。
GooglePlacesAPIとは
Googleが提供するAPIの一つで、地理的な情報(緯度、経度、place_id等)をもとに場所や施設に関する情報を取得できるサービスのこと。取得できる情報は以下の表のとおりです。
取得キー | 内容 |
---|---|
@address_components | 住所の詳細 |
@formatted_address | 住所 |
@formatted_phone_number | 電話番号 |
@icon | Googleマップ上で使われるアイコン画像のURL |
@international_phone_number | 国際電話番号 |
@json_result_object | データがJSON形式でまとめられたもの |
@lat | 緯度 |
@lng | 経度 |
@name | 場所の名前(施設名) |
@opening_hours | 営業時間 |
@photos | 写真データ(配列) |
@place_id | 場所を特定できる一意のid |
@postal_code | 郵便番号 |
@price_level | 価格帯 |
@rating | レビューの星評価の数値 |
@type | 場所の種別 |
@viewport | 建物のある範囲(緯度・軽度で北端と南端を示す) |
@website | 公式サイトのURL |
※主に使用できそうなもののみ記述しております。(他にも取得できるものがあります。)
使い方
APIキーの取得
GooglePlacesAPIを使用するにあたって、APIキーが必要になります。APIキーの取得については、以下の記事を参考にさせていただきました。
APIキーを隠す
GooglePlacesAPIを使用するには、下記のようなエンドポイント(/placeや/photoなど)を含むURLをリクエストを送ります(通常の使い方)。その際にAPIキーが必要になるのですが、URLにそのままAPIキーを使用するのはセキュリティ上よくないので、環境変数を使用して隠します。
https://maps.googleapis.com/maps/api/place/details/json
?place_id=ChIJrTLr-GyuEmsRBfy61i59si0
&fields=address_components
&key=YOUR_API_KEY
私は今回、Railsを使用して個人開発を行なっているため、gem ‘dotenv-rails’を使用して、APIキーを隠す形をとりました。
gem ‘dotenv-rails’については、以下の記事を参考にしました。
(必ず、.gitignoreに.envを記述してからコミットしましょう。)
【Rails】 初心者向け!gem 'dotenv-rails'の使い方 - Qiita
# .env
API_KEY = 取得したAPIキー
$ bin/rails c
irb(main):001:0> ENV['API_KEY']
=> "取得したAPIキー" #表示されていれば環境変数の設定が正常にできています。
※gem ‘dotenv-rails’は、主に開発環境でのみの使用が推奨されているみたいなので、本番環境でAPIキーを環境変数に格納するには、別の方法で格納する必要があります。
私は、herokuを使用して本番環境へデプロイしたので、下記の記事を参考にして、heroku上に環境変数に格納しました。
# heroku上で環境変数にAPIキーを格納
$ heroku config:set API_KEY="取得したAPIキー"
# 環境変数にAPIキーを格納できているか確認
$ heroku run rails c
irb(main):001:0> ENV['API_KEY']
=> "取得したAPIキー"
コンソール上で使用してみる(gem ‘google_places’を使用)
RailsでGooglePlacesAPIを使用する場合、専用のgem ‘google_places’があるので、今回はgemを使用してテストしてみます。
# Gemfime
gem 'google_places'
$ bundle
公式ドキュメント
gemをインストールしたら早速試してみます。
$ bin/rails c
irb(main):001:0> client = GooglePlaces::Client.new(ENV['API_KEY'])
#<GooglePlaces::Client:0x00007f9e10101010 @api_key="自分のAPIキー", @options={}>
irb(main):002:0> spot = client.spots_by_query("+81 570-550-634").first
=>
#<GooglePlaces::Spot:0x00000001111b1ad1
...
irb(main):003:0> spot
=>
#<GooglePlaces::Spot:0x000000011111a1ad1
@address_components=nil,
@aspects=[],
@cid=0,
@city=nil,
@country=nil,
@events=[],
@formatted_address="1-chōme-1-2 Oshiage, Sumida City, Tokyo 131-0045, Japan",
@formatted_phone_number=nil,
@icon="https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/generic_business-71.png",
@id=nil,
@international_phone_number=nil,
@json_result_object=
{"business_status"=>"OPERATIONAL",
"formatted_address"=>"1-chōme-1-2 Oshiage, Sumida City, Tokyo 131-0045, Japan",
"geometry"=>
{"location"=>{"lat"=>35.71006269999999, "lng"=>139.8107004},
"viewport"=>
{"northeast"=>{"lat"=>35.7116204302915, "lng"=>139.81570675},
"southwest"=>{"lat"=>35.7089224697085, "lng"=>139.80606815}}},
"icon"=>"https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/generic_business-71.png",
"icon_background_color"=>"#7B9EB0",
"icon_mask_base_uri"=>"https://maps.gstatic.com/mapfiles/place_api/icons/v2/generic_pinlet",
"name"=>"Tokyo Skytree",
"opening_hours"=>{"open_now"=>true},
"photos"=>
[{"height"=>16320,
"html_attributions"=>
["<a href=\"https://maps.google.com/maps/contrib/110758773056907372323\">Scott Serres</a>"],
"photo_reference"=>
"AUacShhEluHTmTFOfnpvQ6YnSlWyFjKOZakdJ_ZcWMMd_7GCB5wFHq6tCieu6ITlNKtXWjJm7ZBam-AtpYyJJcy7BT2Xjsel2tLsZ-v6AWt8XovBBaMQAV2sYEIF8D_ycV3FWFFQJpfpmXETn8PI3B3uvWPsbn0VDTSmst5WCwBfM4tx10Kc",
"width"=>12240}],
"place_id"=>"ChIJ35ov0dCOGGARKvdDH7NPHX0",
"plus_code"=>{"compound_code"=>"PR66+27 Sumida City, Tokyo, Japan", "global_code"=>"8Q7XPR66+27"},
"rating"=>4.4,
"reference"=>"ChIJ35ov0dCOGGARKvdDH7NPHX0",
"types"=>["tourist_attraction", "point_of_interest", "establishment"],
"user_ratings_total"=>73936},
@lat=35.71006269999999,
@lng=139.8107004,
@name="Tokyo Skytree",
@nextpagetoken=nil,
@opening_hours={"open_now"=>true},
@permanently_closed=nil,
@photos=
[#<GooglePlaces::Photo:0x000000011111fa10
@api_key="自分のAPIキー",
@height=16320,
@html_attributions=["<a href=\"https://maps.google.com/maps/contrib/110758773056907372323\">Scott Serres</a>"],
@photo_reference=
"AUacShhEluHTmTFOfnpvQ6YnSlWyFjKOZakdJ_ZcWMMd_7GCB5wFHq6tCieu6ITlNKtXWjJm7ZBam-AtpYyJJcy7BT2Xjsel2tLsZ-v6AWt8XovBBaMQAV2sYEIF8D_ycV3FWFFQJpfpmXETn8PI3B3uvWPsbn0VDTSmst5WCwBfM4tx10Kc",
@width=12240>],
@place_id="ChIJ35ov0dCOGGARKvdDH7NPHX0",
@postal_code=nil,
@price_level=nil,
@rating=4.4,
@reference="ChIJ35ov0dCOGGARKvdDH7NPHX0",
@region=nil,
@review_summary=nil,
@reviews=[],
@street=nil,
@street_number=nil,
@types=["tourist_attraction", "point_of_interest", "establishment"],
@url=nil,
@utc_offset=nil,
@vicinity=nil,
@viewport=
{"northeast"=>{"lat"=>35.7116204302915, "lng"=>139.81570675},
"southwest"=>{"lat"=>35.7089224697085, "lng"=>139.80606815}},
@website=nil,
@zagat_reviewed=nil,
@zagat_selected=nil>
何をしているか説明すると、
-
「client = GooglePlaces::Client.new(ENV['API_KEY'])」は、GooglePlaceAPIへのアクセスを行うためのクライアント(オブジェクト)を生成しています。
gem ‘google_places’にGooglePlaces::Clientクラスがあるので、そのインスタンスを生成していると考えるとわかりやすいと思います。 -
「spot = client.spots_by_query("+81 570-550-634").first」は、電話番号をもとに’spots_by_query’メソッドでクエリを発行し、最初にマッチした情報をspotに代入しています。’spots_by_query’メソッドは、指定されたクエリに基づいてスポット情報を取得するgem ‘google_places’のメソッドです。(※店名等でも検索ができますが、意図していない情報を取得してしまう可能性があるので、電話番号や住所など一意の情報で検索するのが望ましいと思います。)
-
「spot」で、取得された情報を表示しています。
今回は、「spots_by_query」メソッドを使用して情報を取得しましたが、他にも使用できるメソッドはいくつかあるので気になる方は試してみてください。
コンソール上でテスト(gemを使用しない)
gemを使用しないで取得すると以下のとおりです。
$ bin/rails c
irb(main):001:2* response = HTTparty.get("https://maps.googleapis.com/maps/api/place/details/json", {
irb(main):002:3* query: {
irb(main):003:3* place_id: "ChIJ35ov0dCOGGARKvdDH7NPHX0",
irb(main):004:3* key: ENV['API_KEY']
irb(main):005:2* }
irb(main):006:0> })
HTTPartyを使用して、リクエストを送信し、情報を取得します。
HTTPartyについては、以下の記事に詳しく解説があります。
[Rails] HTTParty gemによるAPIを簡単に利用できる方法 - Qiita
最後に
今回はコンソール上で使用するやり方を説明しました。実際のアプリ開発で使用するにはこれだけでは使用できないので、次回rakeタスクでGooglePlacesAPIを使用し、実際にデータベースに保存する方法を記事にしたいと思います。最後まで見ていただきありがとうございました。