Google Business Profile API × 口コミ自動連携 実装ガイド:開発者向け完全リファレンス
Google Business Profile(GBP)APIで口コミを取得・分析・通知する実装方法を、認証フローからレート制限対策まで開発者向けに解説。Node.js / Python のサンプルコード、Webhookで★1アラートを実装する設計、複数店舗対応のスキーマ設計まで網羅した実務リファレンスです。
こえポスト編集部
お客様の声・口コミ活用の専門家チーム
口コミ管理SaaSを自社で内製化したい、あるいは既存業務システムにGoogle口コミを統合したい——そんな開発者・社内エンジニアに向けて、Google Business Profile API(GBP API)を使った口コミ自動連携の実装ガイドをまとめました。
この記事では、Google公式APIの認証・口コミ取得・更新通知・レート制限対策・複数店舗管理のスキーマ設計まで、運用に乗せるための実践的なコードと設計判断を解説します。
この記事のTL;DR
- GBP APIは申請制。Google My Business API(v4)ではなくBusiness Profile Performance API+My Business Reviews APIの組み合わせ
- 認証はOAuth 2.0、リフレッシュトークン管理が運用上の最大の罠
- 口コミ取得はPolling(1日数回)が現実解。Webhookは非公式
- 多店舗対応はaccount→location→reviewの3階層スキーマで設計
- ★1アラートはSlack/Discord Webhookで即時通知する設計が定番
1. GBP API でできること・できないこと
1.1 できること
| 機能 | エンドポイント |
|------|--------------|
| 店舗(Location)一覧取得 | mybusinessbusinessinformation.googleapis.com |
| 口コミ取得 | mybusiness.googleapis.com/v4/.../reviews |
| 口コミへの返信投稿 | mybusiness.googleapis.com/v4/.../reviews/{id}/reply |
| パフォーマンス分析(表示回数等) | businessprofileperformance.googleapis.com |
1.2 できないこと(重要)
- 新規口コミ投稿(顧客のみ可能)
- 口コミの削除(規約違反のみ申請ベース)
- リアルタイムWebhook(Pub/Sub非対応、Polling必須)
- 競合店舗の口コミ取得
2. 事前準備:API申請とOAuth設定
2.1 APIアクセス申請(数日〜数週間)
- Google Cloud Console でプロジェクト作成
- 「Google My Business API」と「Business Profile APIs」を有効化
- Google Business Profile API アクセス申請フォーム を提出
- 承認まで通常3〜10営業日
重要: 個人事業者・小規模代理店の場合、申請理由を明確に書かないと承認されません。「自社店舗の口コミ管理を内製化する」「クライアント店舗の運用代行ツールを構築する」など、利用目的を具体的に。
2.2 OAuth 2.0 認証情報
スコープは以下:
https://www.googleapis.com/auth/business.manage
2.3 サービスアカウントは使えない
GBP APIはユーザーOAuth認証のみです。サーバー間のサービスアカウント認証は非対応。店舗オーナーのGoogleアカウントでログインしてリフレッシュトークンを取得し、それをDBに保存して長期運用します。
3. 認証フロー実装(Node.js)
import { google } from 'googleapis';
const oauth2Client = new google.auth.OAuth2(
process.env.CLIENT_ID,
process.env.CLIENT_SECRET,
process.env.REDIRECT_URI
);
// 認可URLの生成
const authUrl = oauth2Client.generateAuthUrl({
access_type: 'offline', // 必ずoffline。これがないとrefresh_tokenが取得できない
scope: ['https://www.googleapis.com/auth/business.manage'],
prompt: 'consent', // 既に同意済みでもrefresh_tokenを再取得
});
// コールバックで code を受け取り、tokens を取得
const { tokens } = await oauth2Client.getToken(code);
// tokens.refresh_token を DB に保存(暗号化必須)
3.1 リフレッシュトークン運用の罠
- リフレッシュトークンは初回認証時のみ返ってくる。
prompt: 'consent'を必ず付ける - ユーザーが Googleアカウント設定からアプリを「削除」すると無効化
- 6ヶ月使われないと自動失効するため、最低でも月1回はAPIを叩く運用に
- DB保存時はKMS等で暗号化する。平文保存は重大なセキュリティリスク
4. 口コミ取得:基本フロー
4.1 アカウント → 店舗 → 口コミ の3階層
const mybusiness = google.mybusinessaccountmanagement({ version: 'v1', auth: oauth2Client });
const businessInfo = google.mybusinessbusinessinformation({ version: 'v1', auth: oauth2Client });
// 1. アカウント一覧
const { data: accounts } = await mybusiness.accounts.list();
// 2. 店舗一覧(アカウントごと)
const { data: locations } = await businessInfo.accounts.locations.list({
parent: accounts.accounts[0].name,
readMask: 'name,title,storeCode',
});
// 3. 口コミ取得(v4の旧APIを使う必要あり)
const url = `https://mybusiness.googleapis.com/v4/${locations.locations[0].name}/reviews`;
const res = await oauth2Client.request({ url });
console.log(res.data.reviews);
4.2 取得できる口コミデータ構造
{
"reviewId": "AbF...",
"reviewer": { "displayName": "田中太郎", "profilePhotoUrl": "..." },
"starRating": "FIVE",
"comment": "とても良かったです",
"createTime": "2026-06-08T10:00:00Z",
"updateTime": "2026-06-08T10:00:00Z",
"reviewReply": {
"comment": "ご来店ありがとうございます",
"updateTime": "2026-06-08T12:00:00Z"
}
}
5. Polling 設計:頻度とコストのバランス
5.1 推奨ポーリング頻度
| 店舗規模 | 推奨頻度 | 月間APIコール | |---------|---------|--------------| | 個店(月10件未満) | 6時間ごと | 約120回 | | 中規模(月50件) | 1時間ごと | 720回 | | 多店舗・大規模 | 15分ごと | 2880回/店舗 |
5.2 レート制限と回避策
GBP APIは1分あたりのリクエスト上限があります。多店舗運用では:
- 店舗ごとにポーリングタイミングをずらす(cron 内で店舗インデックスを mod 60)
- 429(Too Many Requests)受信時は指数バックオフ(1s, 2s, 4s, 8s...)
- 増分取得:
updateTimeでソートし、前回ポーリング以降の差分のみ処理
5.3 Python サンプル(cron + 増分取得)
from datetime import datetime, timedelta
import requests
def fetch_new_reviews(location_name, last_polled_at):
url = f"https://mybusiness.googleapis.com/v4/{location_name}/reviews"
headers = { "Authorization": f"Bearer {access_token}" }
res = requests.get(url, headers=headers)
reviews = res.json().get("reviews", [])
return [r for r in reviews if r["updateTime"] > last_polled_at]
6. ★1 アラート Webhook 通知の実装
6.1 設計フロー
[GBP API] → [Polling Worker] → [DB保存] → [★1検知] → [Slack/Discord Webhook通知]
6.2 Slack通知サンプル
async function notifyLowRating(review, locationTitle) {
if (review.starRating !== 'ONE' && review.starRating !== 'TWO') return;
await fetch(process.env.SLACK_WEBHOOK_URL, {
method: 'POST',
body: JSON.stringify({
text: `:warning: 低評価口コミ受信`,
attachments: [{
color: 'danger',
title: `${locationTitle} - ★${review.starRating}`,
text: review.comment,
footer: `投稿者:${review.reviewer.displayName} / ${review.createTime}`,
}],
}),
});
}
返信文ドラフトをAIで自動生成し、Slack上で承認→投稿のワークフローまで組むと、**24時間以内対応率がほぼ100%**になります。返信テンプレはネガティブ口コミ返信テンプレを参照。
7. 多店舗対応のスキーマ設計
7.1 推奨DBスキーマ
CREATE TABLE accounts (
id UUID PRIMARY KEY,
google_account_id TEXT UNIQUE,
refresh_token TEXT, -- 必ず暗号化保存
last_token_refresh_at TIMESTAMPTZ
);
CREATE TABLE locations (
id UUID PRIMARY KEY,
account_id UUID REFERENCES accounts(id),
google_location_id TEXT UNIQUE,
store_code TEXT,
title TEXT,
last_polled_at TIMESTAMPTZ
);
CREATE TABLE reviews (
id UUID PRIMARY KEY,
location_id UUID REFERENCES locations(id),
google_review_id TEXT UNIQUE,
star_rating SMALLINT,
comment TEXT,
reviewer_name TEXT,
created_at TIMESTAMPTZ,
updated_at TIMESTAMPTZ,
reply_comment TEXT,
reply_updated_at TIMESTAMPTZ
);
CREATE INDEX reviews_location_updated ON reviews(location_id, updated_at DESC);
7.2 多店舗運用との連携
本DBスキーマは、多店舗チェーン店向けダッシュボードの基盤になります。BIツール(Looker, Metabase等)から直接参照可能な構造です。
8. 返信投稿API:自動返信は危険、ドラフト生成のみ推奨
8.1 返信投稿エンドポイント
const replyUrl = `https://mybusiness.googleapis.com/v4/${reviewName}/reply`;
await oauth2Client.request({
url: replyUrl,
method: 'PUT',
data: { comment: '返信文' },
});
8.2 完全自動返信は推奨しない理由
- AI生成返信が炎上を招くケースあり(皮肉理解失敗)
- ネガティブ口コミに自動返信すると法的リスク表現を含むことがある
- 「人間がレビューしてから投稿」のワークフローが定石
推奨は[AIで返信ドラフト生成 → Slackで承認 → 投稿API実行]の3段階フロー。
9. エラーハンドリングと監視
9.1 主要エラーコード
| コード | 意味 | 対応 | |--------|------|------| | 401 | 認証失敗 | リフレッシュトークンで再発行 | | 403 | 権限不足 | スコープ・店舗管理権限を確認 | | 429 | レート制限 | 指数バックオフ | | 500/503 | サーバーエラー | リトライ(最大3回) |
9.2 監視必須指標
- リフレッシュトークン更新失敗率
- ポーリング遅延(last_polled_at - now)
- 口コミ取得件数の異常変動(前日比50%以上の変化)
10. 実装後の運用:3つの落とし穴
10.1 リフレッシュトークン失効ラッシュ
ユーザーが「Googleアカウント設定 → セキュリティ → サードパーティアプリ」で削除すると、リフレッシュトークンが無効化されます。週次でトークン健全性をチェックし、失効時は再認証URLをユーザーに送るフローを。
10.2 店舗オーナー変更時の再認証
店舗の管理権限が別のGoogleアカウントに移譲されると、旧トークンは無効化されます。店舗オーナー変更検知の運用が必要です。
10.3 APIの破壊的変更
Google My Business APIは段階的にBusiness Profile APIs群へ移行中です。Deprecation noticeをモニタリングし、半年ごとに移行計画を更新してください。
まとめ:自社実装と SaaS導入の判断基準
GBP APIの自社実装は技術的には可能ですが、運用負荷が想像以上に重いのが現実です。
| 観点 | 自社実装 | こえポスト 等 SaaS | |------|---------|------------------------------| | 初期コスト | エンジニア工数200h〜 | 月額数千円〜 | | 運用負荷 | リフレッシュトークン・API変更追随 | ベンダーが吸収 | | カスタマイズ性 | 完全自由 | テンプレート範囲内 | | BI連携 | 自由設計 | エクスポート機能で対応 |
社内に専任エンジニアがいる場合は自社実装、それ以外はこえポストのような口コミ管理SaaSでAPIラッパー込みの運用を任せる方が、ROIは圧倒的に高くなります。
エンジニアの方は、まず本記事のサンプルコードを1店舗・1日1回のPollingから動かしてみてください。GBP APIの世界が手触り感を持って理解できるはずです。
お客様にレビューをお願いする文面に困っていませんか?業種とシーンを選ぶだけで、すぐ使える依頼メッセージが完成します。
依頼文ジェネレーター(無料)を使うフォームにどんな質問を入れればいいか迷ったら。業種ごとのテンプレートから最適な質問セットを選べます。
質問テンプレート作成ツール(無料)を使うお客様の声の集め方Tips
テスティモニアルの効果的な集め方・活用方法を週1回お届け。 業種別の成功事例や、すぐ使えるテンプレートも配信します。