Google Business Profile接続・拠点取込
Google接続リンクを作成し、オーナーのGoogle掲載情報を自分の拠点と照合して対応関係を確定し、対応する拠点がまだない掲載情報をインポートします。
Google アカウントを接続すると、Google 上で拠点の情報を公開し、レポートを取得できます。アカウントを接続するまでは、拠点のプレミアム掲載情報にある Google Maps の行は REQUIRING_ACTION のままで、Google のレビューは取り込まれず、GOOGLE に投稿を公開できず、Google の分析データは null として返されます。アカウントを接続すると、この 4 つすべてが解消されます。
一括接続の手順(手順 1~6)では、Google アカウント全体を一度に接続し、そのアカウントが所有するすべての掲載情報を拠点と照合します。拠点ごとの接続手順(手順 7)では、1 つずつ拠点を接続します。リンクがその拠点に紐づいているため、その後の照合手順はありません。
1. 接続リンクを作成し、所有者をリダイレクトする
リンクの対象範囲は API キーを所有するアカウントに限定されるため、リクエストボディに含めるのは 2 つのリダイレクト URL のみです。返された url に所有者を誘導してください。所有者が操作を完了すると、Google は所有者を successUrl または errorUrl に戻します。
curl -X POST https://listingsapi.com/api/v4/connected-accounts/connect-google \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "successUrl": "https://app.example.com/connect/google/success", "errorUrl": "https://app.example.com/connect/google/error" }}'{ "data": { "bulkConnectLinkForGoogle": { "success": true, "url": "https://connect.example.com/oauth?token=8f3c1d92-...", "errors": null } }}上記の url はプレースホルダーです。ご自身のレスポンスで返された url に所有者を誘導してください。
リンクの有効期間は 24 時間です。success だけで判断せず、url が null でないことを確認してください。後で所有者の認証情報の有効期限が切れた場合は、同じ方法で新しいリンクを作成してください。既存の接続が更新され、重複する接続は作成されません。
2. OAuth から戻った後に接続済みアカウントを一覧表示する
所有者が successUrl に戻ったら、Google アカウントの一覧を取得します。この一覧はオフセット方式でページ分割されており、records[] と pageInfo.totalRecords を含み、page と perPage でページを指定します。
curl "https://listingsapi.com/api/v4/connected-accounts?publisher=GoogleAccount&page=1&perPage=20" \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "connectedAccountsInfo": { "pageInfo": { "hasNextPage": false, "totalRecords": 1 }, "records": [ { "connectedAccountId": "4f712c17-4f95-42dd-90f4-97171a2e67b5", "email": "owner@brightsmile-dental.com", "status": "CONNECTED", "requestMatchesStatus": "MATCH_COMPLETED", "connectedLocationsCount": 0 } ] } }}email が同意を完了した所有者であるレコードを選択し、その connectedAccountId を保持します。以降のすべての呼び出しで、この UUID を渡します。
省略可能な status クエリフィルターでは、異なる値(Connected、NotConnected、ConnectionIssue)を使用します。レコード自身の status をそのまま渡すと、400 が返されます。
3. マッチングを開始する
マッチングでは、アカウントがアクセスできるすべてのプロフィールを取得し、それぞれをご自身の拠点のいずれかと組み合わせます。生成されるのは候補のみで、この時点では何も紐づけられません。
curl -X POST https://listingsapi.com/api/v4/connected-accounts/trigger-matches \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "connectedAccountIds": ["4f712c17-4f95-42dd-90f4-97171a2e67b5"] } }'レスポンスは data.connectedAccountsTriggerMatches で、success と failedIds を含みます。success: true はジョブがキューに登録されたことを意味し、キューに登録できなかったアカウントは failedIds に一覧表示されます。
4. MATCH_COMPLETED になるまでポーリングする
上限を設けたループで、15 秒ごとにアカウントの詳細をポーリングします。この間隔であれば、Launch プランでも 1 分あたり 10 リクエストの制限内に収まります。
curl https://listingsapi.com/api/v4/connected-accounts/4f712c17-4f95-42dd-90f4-97171a2e67b5/details \-H "Authorization: API $LISTINGSAPI_KEY"レコードは data.connectedAccountDetails.details に返され、一覧内のレコードと同じフィールドを持ちます。requestMatchesStatus は、ジョブの実行中は MATCH_IN_PROGRESS、候補の準備ができると MATCH_COMPLETED になります。Completed は照合処理が完了したことを意味し、何かが紐づけられたことを意味するわけではありません。確定するまで、connectedLocationsCount は 0 のままです。
5. 候補を確認して確定する
各候補は、ご自身の拠点の 1 つ(locationInfo。その databaseId は locationId)と、Google の掲載情報 1 件(suggestedLocationInfo)の組み合わせです。両方の情報を担当者に表示するか、名前と市区町村が一致する場合に自動で承認します。
curl "https://listingsapi.com/api/v4/connected-accounts/4f712c17-4f95-42dd-90f4-97171a2e67b5/connection-suggestions?page=1&perPage=20" \-H "Authorization: API $LISTINGSAPI_KEY"{ "data": { "connectionSuggestionsForAccount": { "pageInfo": { "hasNextPage": false, "totalRecords": 2 }, "records": [ { "accountType": "GMB", "matchedDataDatabaseId": "0d5e306f-0da0-46e3-929f-fd3c67ccd8cc", "locationId": "73415", "locationInfo": { "name": "My Business", "city": "Lincoln", "stateIso": "NE" }, "suggestedLocationInfo": { "locationInfo": { "name": "My Business", "city": "Lincoln" } } } ] } }}候補には id がありません。候補を確定するには、accountType から選んだ型を使用し、<MatchRecordType>:<matchedDataDatabaseId> を base64 でエンコードして照合レコードの id を作成します。Google(GMB)の型は GmbLocationMatchedData なので、上記のレコードをエンコードすると R21iTG9jYXRpb25NYXRjaGVkRGF0YTowZDVlMzA2Zi0wZGEwLTQ2ZTMtOTI5Zi1mZDNjNjdjY2Q4Y2M= になります。Facebook(FB)では FbLocationMatchedData、Apple(APPLE)では AppleLocationMatchedData を使用します。
# base64 of GmbLocationMatchedData:0d5e306f-0da0-46e3-929f-fd3c67ccd8cccurl -X POST https://listingsapi.com/api/v4/connected-accounts/confirm-matches \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "matchRecordIds": ["R21iTG9jYXRpb25NYXRjaGVkRGF0YTowZDVlMzA2Zi0wZGEwLTQ2ZTMtOTI5Zi1mZDNjNjdjY2Q4Y2M="] } }'レスポンスは data.confirmConnectMatches で、success と failedIds を含みます。failedIds には、すでに使用済みのレコードや、マッチング後にアーカイブされた拠点など、確定できなかったもののデコード済み matchedDataDatabaseId 値が格納されます。誤った型で作成した id を渡しても 400 は返されず、呼び出しは success: false を含み failedIds を含まない 200 を返すため、毎回 success を確認してください。送信しなかった候補は変更されません。
6. 拠点がまだない掲載情報をインポートする
マッチングでは、掲載情報と既存の拠点のみを対応付けます。残りをインポートするには、アカウントから参照できるすべての掲載情報を一覧表示し、必要な掲載情報ごとに拠点を作成します。
curl -X POST https://listingsapi.com/api/v4/connected-accounts/connected-account-listings \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "connectedAccountId": "4f712c17-4f95-42dd-90f4-97171a2e67b5", "perPage": 50 }'{ "data": { "connectedAccountListings": { "pageInfo": { "hasNextPage": false, "totalRecords": 60 }, "records": [ { "id": "R21iQnVsa0RhdGFMYWtlOjA2MDQ4NmExLTA0NzQtNDc4NS1iMjNhLTBkOGM4MzhmNGQ5OA==", "locationName": "Trial", "address": "123 William St, NY 10038, Manhattan, US", "liveLink": null } ] } }}掲載情報の多いアカウントでは、locationInfo に検索語を指定すると、名前、住所、電話番号、郵便番号、店舗コードで絞り込めます。各レコードの id は、次の 2 つの呼び出しで受け取る connectedAccountListingId です。どちらの SDK も create-location-from-listing のラッパーをまだ提供していないため、Python と Node のサンプルでは、同じヘッダーを使用して REST を直接呼び出します。
curl -X POST https://listingsapi.com/api/v4/connected-accounts/create-location-from-listing \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "connectedAccountId": "4f712c17-4f95-42dd-90f4-97171a2e67b5", "connectedAccountListingId": "R21iQnVsa0RhdGFMYWtlOjA2MDQ4NmExLTA0NzQtNDc4NS1iMjNhLTBkOGM4MzhmNGQ5OA==" }}'{ "data": { "createLocationFromConnectedAccountListing": { "success": true, "locationId": 88277, "errors": null } }}Google のデータ(名前、住所、営業時間、カテゴリ、電話番号、属性)から拠点が作成され、その場で元の掲載情報にリンクされます。Google の掲載情報は、拠点への最初の更新がその掲載情報に公開されるまで IN_PROGRESS のままです。locationId は、そのままの databaseId です。失敗すると、success は false となり、errors には SY81067(掲載情報の id に対応する掲載情報が見つからなかった)などのコードが含まれます。フィールド名は connectedAccountListingId です。listingId はスキーマで拒否されます。
掲載情報が既存の拠点に属している場合は、重複する拠点を作成せず、その掲載情報をリンクします。
curl -X POST https://listingsapi.com/api/v4/connected-accounts/connect-listing \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "connectedAccountId": "4f712c17-4f95-42dd-90f4-97171a2e67b5", "connectedAccountListingId": "R21iQnVsa0RhdGFMYWtlOjA2MDQ4NmExLTA0NzQtNDc4NS1iMjNhLTBkOGM4MzhmNGQ5OA==" }}'リンクに失敗すると、success: false とともに、Listing record not found などの message、または掲載情報がすでに別の拠点に接続されていることを示すメッセージが返されます。
7. 代わりに単一の拠点を接続する
オーナーがどの拠点を接続するかがすでにわかっている場合は、マッチングを省略し、その拠点に紐づくリンクを作成します。成功すると、オーナーは指定した successUrl に戻り、認証情報はその拠点にのみ紐づけられます。
curl -X POST https://listingsapi.com/api/v4/locations/oauth_connect_url \-H "Authorization: API $LISTINGSAPI_KEY" \-H "Content-Type: application/json" \-d '{ "input": { "locationId": "TG9jYXRpb246MTgwMDI4OQ==", "site": "GOOGLE", "successUrl": "https://app.example.com/locations/1800289/connected", "errorUrl": "https://app.example.com/locations/1800289/connect-failed" }}'レスポンスは data.createConnectUrl で、success、url、errors が含まれます。リンクは 1 回限り有効なので、試行ごとに新しいリンクを作成します。リダイレクト URL が相対 URL または解析できない URL の場合は、null url を伴う success: true が返されるため、url を確認してください。この拠点へのアクセス権限がないキーを使用すると、SY90003 を伴う 403 が返されます。
8. 接続後の動作
掲載情報をリンクすると、拠点のプレミアム掲載情報にある Google Mapsの行は REQUIRING_ACTION から IN_PROGRESS に移行し、最終的に listingUrl を伴う SYNCED になります。Google はレビューの取得元として自動的に追加されるため、インタラクション一覧にレビューが届き始め、拠点に加えた更新はプロフィールに反映されます。
ダッシュボードで Webhook URL を設定すると、ポーリングは不要です。各ペイロードには location_id と data.connected_account_id が含まれます。
次の手順
- Google Business Profile を作成する:マッチング対象の Google の掲載情報がない拠点向けです。
- Facebook ページを接続する:もう一方の OAuth 掲載先でも、同じ手順を使用します。
- 掲載情報のステータスと公開リンクを確認する、レビューを取得する:結果が届くことを確認します。
- SDK リファレンス:Python の接続済みアカウント、Node の接続済みアカウント。
- リファレンス:Google アカウントを接続する、拠点のマッチングを実行する、接続のマッチング結果を確定する、接続済みアカウントの掲載情報を取得する、掲載情報から拠点を作成する、接続済みアカウントの索引。