実験ログ 約3分で読めます
【実験ログ】Google Maps Places APIで店舗写真を自動取得する仕組みを作った
課題
旅行メディアの記事で店舗やスポットを紹介するとき、写真がないと読者がクリックする気にならない。しかし:
- 食べログの写真 → 著作権NG
- Google Mapsの写真 → 直接ダウンロードNG
- Wikimedia Commons → ホットリンクがブロックされる
- Unsplash → 特定の店舗の写真はない
解決策
Google Maps Places API (New) を使い、ビルド時に写真URLを取得してHTMLに埋め込む。
ビルド時(npm run build)
↓
SpotCardのmapQueryで店名を検索
↓
Places APIから写真URLを取得
↓
HTMLにimgタグとして埋め込み
↓
デプロイ後はAPIを呼ばない(静的HTML)
実装
1. Google Cloud PlatformでAPIキーを取得
- Places API (New) を有効化
- APIキーを作成
- ウェブサイト制限はなし(ビルドはサーバーから呼ぶため)
- API制限は Places API のみ
2. places.ts(API呼び出し関数)
const API_KEY = import.meta.env.GOOGLE_PLACES_API_KEY;
export async function getPlacePhoto(query: string) {
// 1. テキスト検索でplaceを取得
// 2. 写真のリファレンスを取得
// 3. 写真URLを返す
}
3. SpotCardコンポーネント
imageプロパティが指定されていない場合、mapQueryからPlaces APIで写真を自動取得。取得できなければGoogle Maps iframeをフォールバック表示。
4. Cloudflare Pages の環境変数
GOOGLE_PLACES_API_KEY をCloudflareの環境変数に設定。ビルド時に読み込まれる。
料金
| 項目 | 料金 |
|---|---|
| 毎月の無料枠 | $200分(約28,000リクエスト) |
| 1回のビルドで使うリクエスト | 記事内のSpotCard数(10〜20程度) |
| 月の実コスト | $0(無料枠内) |
💡
ビルド時に1回だけ呼ぶのがミソ
閲覧者がページを見るたびにAPIを呼ぶのではなく、ビルド時に写真URLをHTMLに埋め込む。だからAPIコストが最小限で済む。
ハマったポイント
APIキーのウェブサイト制限
最初にウェブサイト制限(trip-journal.netのみ)を設定したら、Cloudflareのビルドサーバーからの呼び出しがブロックされた。
解決: ウェブサイト制限を外し、API制限(Places APIのみ)だけ残す。
写真のクレジット表示
Places APIから取得した写真にはauthorAttributionsが付いている。SpotCardの写真下に小さくクレジットを表示。