RubyでGoogle Places APIをフル活用！簡単スタートガイド

# Google Places APIとは
Google Places APIは、Googleのデータベースを使いあらゆる場所や施設を検索し、取得することができるAPIです。
このAPIを使用することで、位置情報や検索クエリに基づいてスポットを検索したりすることができます。

## Google Places APIキーの取得
Google Places APIを使用するには、APIキーが必要です。

### 1.Google Cloudプロジェクトの作成
Google Cloud ConsoleでAPIキーを紐付けるためのプロジェクトを作成します。

まずは以下の公式サイトにアクセスします。

https://console.cloud.google.com/

**プロジェクトを作成または選択**を選択します。
![create-or-select-project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/743b11da-6c5c-c9f9-0411-6395d7ec0947.png)

**新しいプロジェクト**を選択します。
![new-project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/01b379fa-cde4-f3a1-a1b7-2a0216b76760.png)

任意のプロジェクト名、任意の組織を選択して**作成**を選択して、プロジェクトを作成します。
![create-project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/d27f06bb-7517-9545-2f08-921ca85546a1.png)

### 2.Google Places APIの有効化
作成したプロジェクトでGoogle Places APIを使用できるようにします。

再度**プロジェクトを作成または選択**を選択します。
![create-or-select-project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/743b11da-6c5c-c9f9-0411-6395d7ec0947.png)

作成されたプロジェクトが表示されるので選択します。
![select-project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/63e7d0f3-52e9-204d-f6cc-0ab6f1336ddf.png)

左上のハンバーガーメニューをクリックして**APIとサービス**から**ライブラリ**を選択します。
![library.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/311cb340-a36e-de40-6ac7-4172cf8adffd.png)

今回はPlaces APIを使用したいので、**Places API**を選択します。
![places-api.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/2c12ef10-a8ae-d097-fd6a-a79dbd217c6c.png)

**有効にする**ボタンをクリックします。
![enable.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/84f718f6-473b-7022-603f-1f1ed65f91a4.png)

### 3.APIキーの生成
APIキーを生成することで、プロジェクトがGoogle Places APIにアクセスするための認証情報を取得します。

**APIとサービス**から**認証情報**を選択します。
![configure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/8bd146a0-b183-bfde-ae6c-757aabeb0239.png)

**認証情報を作成**から**APIキー**を選択します。
![create-apikey.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/1dc6d50d-51e7-9a26-93b4-aace210b3448.png)

APIキーが作成されるのでメモしておきます。
![apikey.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/21fbea13-bd1a-9816-e21f-385602054c87.png)

作成されたAPIキーを選択します。
![スクリーンショット 2024-02-29 13.27.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/3c037823-cc6b-4ce0-56ee-bec6e72bed62.png)

この画面からアプリケーションやAPIの制限を行うことができます。
![スクリーンショット 2024-02-29 13.31.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458297/39e2d3e6-bfaf-6728-f81d-a887d53b0401.png)

# Google Places gem
Google Places gemは、Places APIを利用するための便利なツールです。
このGemを使用することで、簡単にGoogle Places APIを呼び出し、レスポンスを処理することができます。
このセクションでは、gemのインストール方法から、基本的な使用方法について説明します。

## Gemの追加とインストール
プロジェクトの`Gemfile`に`google_places`を追加し、`bundle install`コマンドを実行してインストールします。
```ruby:Gemfile
gem 'google_places'
```
```bash
$ bundle install
```

## Google Places APIクライアントの設定
APIを使用するためには、まずクライアントを設定する必要があります。
以下のコードを使用して、APIキーを用いて新しいクライアントを作成します。
```ruby
@client = GooglePlaces::Client.new('YOUR_API_KEY')
```

## スポットの検索と属性の解説
Google Places gemを利用することで、特定の条件に基づく場所の検索が可能です。
GooglePlaces::Spotオブジェクトを使用して、緯度と経度、または特定のクエリに基づいてスポットを検索し、各スポットの属性を取得することができます。

### スポットの属性
検索結果として得られる各スポットには、以下のような属性が含まれます。

| 属性名                   | 説明                                                    |
|------------------------|---------------------------------------------------------|
| place_id               | 場所の一意のID                                           |
| name                   | 場所の名前                                               |
| formatted_address      | 整形された住所                                           |
| types                  | 場所の種類（複数指定可能）                               |
| lat                    | 緯度                                                     |
| lng                    | 経度                                                     |
| rating                 | ユーザーからの評価の平均値                               |
| user_ratings_total     | 評価の総数                                               |
| vicinity               | その場所の近くの住所                                     |
| international_phone_number | 国際電話番号                                      |
| website                | 場所のウェブサイトURL                                    |
| opening_hours          | 開店時間（曜日ごとの開店・閉店時間）                     |
| photos                 | 場所の写真。各写真はphoto_referenceを使用してアクセス可能 |
| price_level            | 料金レベル（0から4の範囲）                               |
| reviews                | ユーザーレビューのリスト                                 |
| icon                   | 場所を示すアイコンのURL                                  |
| geometry               | 場所のジオメトリ（緯度・経度）                           |

これらの属性を利用することで、アプリケーションやサービスにスポットの情報を組み込むことが可能になります。
特定の属性の利用方法や詳細については、Google Places APIの公式ドキュメントを参照してください。

### 検索方法の例
#### 緯度と経度に基づく検索
最も基本的な検索方法として、緯度と経度を使用します。
これは、特定の地点の近くにあるスポットを見つける際に便利です。
```ruby
@client.spots(35.681236, 139.767125)
```
#### クエリに基づく検索
次に、特定のキーワードや名前でスポットを検索する方法です。
これは、特定の場所や施設を探しているときに有用です。
```ruby
@client.spots_by_query('東京駅')
```
#### 特定のタイプで検索
特定のタイプのスポットを検索する方法です。
例えば、レストランやホテルなど、特定のカテゴリに属するスポットを見つけたい場合に使用します。
```ruby
@client.spots(35.681236, 139.767125, :types => 'restaurant')
```
#### 複数のタイプで検索
複数のタイプを指定して検索することもできます。
これは、複数のカテゴリにまたがる検索を行いたいときに便利です。
```
@client.spots(35.681236, 139.767125, :types => ['restaurant','food'])
```
#### 複数のタイプを検索し、特定のタイプを除外
指定したタイプに一致し、かつ特定のタイプを除外して検索する方法です。
これにより、検索結果をより絞り込むことができます。
```
@client.spots(35.681236, 139.767125, :types => ['restaurant','food'], :exclude => 'cafe')
```
#### 名前で検索
特定の名前を含むスポットを検索します。
名前を基にした検索では、その名前を含むすべてのスポットが結果として返されます。
```ruby
@client.spots(35.681236, 139.767125, :name => 'italian')
```
#### 名前とタイプで検索
名前とタイプの両方を指定して検索する方法です。
これにより、さらに検索結果を絞り込むことができます。
```ruby
@client.spots(35.681236, 139.767125, :name => 'italian', :types => 'restaurant')
```
#### 半径で検索（メートル単位）
特定の地点から指定した半径内にあるスポットを検索します。
これは、特定の範囲内でスポットを探したいときに有用です。
```ruby
@client.spots(35.681236, 139.767125, :radius => 100)
```
#### 特定の言語で結果を取得
指定した言語でスポット情報を取得します。
これにより、特定の言語のユーザーに適した結果を提供できます。
```ruby
@client.spots(35.681236, 139.767125, :language => 'ja')
```
#### 特定のスポットを取得
`@client.spots`や`@client.spots_by_query`で取得したスポットのIDを指定して、詳細情報を取得します。
```ruby
@client.spot('CmRYAAA...upoTH3g')
```
#### 特定のフィールドのみを取得
特定のスポットから特定のフィールドの情報のみを取得します。
これにより、必要な情報だけを素早く取得できます。
```ruby
@client.spot('CmRYAAA...upoTH3g', fields:'place_id,name')
```
#### 単一の写真のURLを取得
特定のスポットに関連付けられた写真を取得します。
```ruby
url = @spot.photos[0].fetch_url(800)
```
## 実際の使用例
### 検索例：東京駅周辺のレストランを探す
東京駅周辺で食事をしたい場合、Google Places gemを使用して周辺のレストランを検索することができます。
以下のコードは、東京駅の座標を基点として、周辺のレストランの情報を取得する方法を示しています。
typesオプションに'restaurant'を指定することで、レストランに特化した検索結果を得ることができます。
```ruby
restaurants = @client.spots(35.681236, 139.767125, types: 'restaurant', radius: 500, language: 'ja')
```
このコードは、東京駅の座標を中心とした半径500メートル以内にあるレストランを検索します。
検索結果はGooglePlaces::Spotオブジェクトの配列として返され、それぞれのレストランに関する情報が含まれます。

### 詳細情報の取得
検索結果から特定のレストランに興味を持った場合、そのレストランのplace_idを使用して、さらに詳細な情報を取得することが可能です。
以下のコードは、特定のレストランの詳細情報を取得する方法を示しています。

```ruby
detailed_restaurant = @client.spot('place_id', language: 'ja')
```
このメソッドを使用すると、営業時間、ユーザーレビューなど、より詳細な情報を取得できます。

# 注意点とベストプラクティス
Google Places APIを利用する際には、コスト管理とセキュリティを考慮することが重要です。

## コスト管理
Google Places APIは、利用量に応じた料金が発生するサービスです。
そのため、APIリクエストの数が多くなるほど、コストが増加します。
Google Places APIには無料枠が設定されていますが、この無料枠を超えると料金が発生するため、コスト管理には注意が必要です。
### 無料枠の活用
Google Places APIには、無料で利用できるリクエスト数の枠が設定されています。
Google Cloud Platformのダッシュボードで、定期的に使用状況を確認し、無料枠内での利用を心掛けましょう。
### 予算アラートの設定
Google Cloud Platformでは予算アラートを設定できます。
設定した予算に近づいた場合、通知を受けることで、予期せぬ料金発生を防ぐことができます。
### リクエストの最適化
不必要なリクエストは避け、必要な情報のみをリクエストするようにしましょう。
### キャッシングの利用
よくアクセスする情報はキャッシュしておくことで、APIリクエスト数を減らし、コスト削減につながります。

これらの対策を講じることで、Google Places APIの無料枠内で効率的にサービスを利用し、予期せぬ高額な請求を避けることができます。

## セキュリティ
### APIキーの保護
APIキーは、不正利用を防ぐために厳重に保護する必要があります。
APIキーをコードに直接埋め込む代わりに、環境変数や設定ファイルから読み込む方法を検討しましょう。
また、Google Cloud ConsoleでAPIキーのリファラー制限を設定することで、キーの不正利用リスクを低減できます。

Google Places APIを効果的かつ安全に利用するために、これらの注意点とベストプラクティスを適切に適用してください。


# まとめ
この記事は、Google Places APIを利用して地域や施設の情報を取得し、アプリケーションやサービスに組み込む方法についての基本的な利用方法を説明しました。
コストとセキュリティの管理を適切に行い、このAPIを効果的かつ安全に活用してください。

間違っている箇所や疑問に思ったことがあれば、ぜひコメントをください！
最後まで読んでいただき、ありがとうございました。