本教程旨在解決在使用Google My Business Business Information API v1獲取商家位置列表時,因readMask參數格式不正確導致的INVALID_ARGUMENT錯誤。核心在于,readMask必須指定location資源自身的有效字段,而非其他關聯資源或無效字段,以確保API請求的成功執行和數據的精準獲取。
隨著google my business api的迭代更新,尤其是從v4版本向更細粒度的服務(如businessinformation)遷移,開發者需要適應新的api結構和參數要求。在獲取商家位置列表時,readmask參數是控制返回數據字段的關鍵,它允許客戶端只請求所需的數據,從而提高性能并減少帶寬消耗。
問題解析:readMask參數的誤用
在使用Google_Service_MyBusinessBusinessInformation服務的accounts.locations.list方法時,開發者可能會遇到http 400 INVALID_ARGUMENT錯誤,具體錯誤信息為Invalid field mask provided。這通常是由于readMask參數中包含了API不識別或不屬于Location資源直接屬性的字段。
例如,以下代碼片段展示了一個常見的錯誤用法:
<?php require __DIR__ . '/vendor/autoload.php'; // 假設您使用composer管理依賴 use GoogleClient; use GoogleServiceMyBusinessAccountManagement; use GoogleServiceMyBusinessBusinessInformation; use GoogleServiceException; // 假設 $client 已經正確初始化并完成了認證 // 通常需要設置應用憑據或用戶憑據 $client = new Client(); $client->setAuthConfig('path/to/your/credentials.json'); // 替換為您的憑據文件路徑 $client->addScope('https://www.googleapis.com/auth/business.manage'); // 必要的API范圍 try { $my_business_account = new MyBusinessAccountManagement($client); $list_accounts_response = $my_business_account->accounts->listAccounts(); if (empty($list_accounts_response->getAccounts())) { echo "未找到任何賬戶。n"; exit; } $account = $list_accounts_response->getAccounts()[0]; // 獲取第一個賬戶 $mybusinessService = new MyBusinessBusinessInformation($client); $locations = $mybusinessService->accounts_locations; $queryParams = [ "pageSize" => 10, // 錯誤示例:readMask 包含了非 Location 資源自身的字段 'readMask' => "user.display_name,photo" ]; $locationsList = $locations->listAccountsLocations($account->name, $queryParams); // 處理返回的位置數據 if ($locationsList->getLocations()) { foreach ($locationsList->getLocations() as $location) { echo "Location Name: " . $location->getName() . "n"; // 嘗試訪問 readMask 中指定的字段,但這里會因為 readMask 錯誤而無法獲取正確數據 } } else { echo "未找到任何位置。n"; } } catch (Exception $e) { echo "發生錯誤: " . $e->getMessage() . "n"; if ($e->getCode() === 400) { // 嘗試解析更詳細的錯誤信息 $errors = json_decode($e->getMessage(), true); if (isset($errors['error']['details'][0]['fieldViolations'][0]['description'])) { echo "錯誤詳情: " . $errors['error']['details'][0]['fieldViolations'][0]['description'] . "n"; } } }
上述代碼中,readMask被設置為”user.display_name,photo”。然而,user.display_name和photo并非Location資源(https://developers.google.com/my-business/reference/businessinformation/rest/v1/locations)的直接頂級字段。readMask參數僅支持指定Location對象本身的屬性,例如name、title、storeCode、websiteUri等。試圖訪問非直接屬性會導致API服務器拒絕請求,并返回INVALID_ARGUMENT錯誤。
解決方案:正確構建readMask
解決此問題的關鍵在于,嚴格按照Google My Business Business Information API的Location資源定義來構建readMask。這意味著readMask中列出的字段必須是Location對象中直接可用的屬性。
以下是一些Location資源常用的有效字段示例:
- name:資源的完整名稱,包括賬戶和位置ID。
- title:商家在Google Maps上顯示的名稱。
- storeCode:商家內部用于識別位置的唯一代碼。
- websiteUri:商家的官方網站URL。
- phoneNumbers:商家的聯系電話信息。
- address:商家的物理地址。
- latlng:商家的經緯度。
- openInfo:商家的營業狀態信息。
- regularHours:商家的常規營業時間。
- categories:商家的業務類別。
修正后的代碼示例:
<?php require __DIR__ . '/vendor/autoload.php'; // 假設您使用Composer管理依賴 use GoogleClient; use GoogleServiceMyBusinessAccountManagement; use GoogleServiceMyBusinessBusinessInformation; use GoogleServiceException; // 假設 $client 已經正確初始化并完成了認證 $client = new Client(); $client->setAuthConfig('path/to/your/credentials.json'); // 替換為您的憑據文件路徑 $client->addScope('https://www.googleapis.com/auth/business.manage'); // 必要的API范圍 try { $my_business_account = new MyBusinessAccountManagement($client); $list_accounts_response = $my_business_account->accounts->listAccounts(); if (empty($list_accounts_response->getAccounts())) { echo "未找到任何賬戶。n"; exit; } $account = $list_accounts_response->getAccounts()[0]; // 獲取第一個賬戶 $mybusinessService = new MyBusinessBusinessInformation($client); $locations = $mybusinessService->accounts_locations; $queryParams = [ "pageSize" => 10, // 正確示例:readMask 包含了 Location 資源自身的有效字段 'readMask' => "name,title,storeCode,websiteUri,address" ]; $locationsList = $locations->listAccountsLocations($account->name, $queryParams); if ($locationsList->getLocations()) { echo "成功獲取商家位置列表:n"; foreach ($locationsList->getLocations() as $location) { echo "----------------------------------------n"; echo "位置名稱 (API Name): " . $location->getName() . "n"; echo "商家標題 (Title): " . $location->getTitle() . "n"; echo "門店代碼 (Store Code): " . $location->getStoreCode() . "n"; echo "網站URI (Website URI): " . $location->getWebsiteUri() . "n"; // 獲取地址信息,地址是一個對象,需要進一步解析 $address = $location->getAddress(); if ($address) { echo "地址: " . $address->getPostalCode() . " " . $address->getLocality() . ", " . $address->getAdministrativeArea() . ", " . $address->getRegionCode() . "n"; } } } else { echo "未找到任何位置。n"; } } catch (Exception $e) { echo "發生錯誤: " . $e->getMessage() . "n"; if ($e->getCode() === 400) { $errors = json_decode($e->getMessage(), true); if (isset($errors['error']['details'][0]['fieldViolations'][0]['description'])) { echo "錯誤詳情: " . $errors['error']['details'][0]['fieldViolations'][0]['description'] . "n"; } } }
注意事項與最佳實踐
- 查閱官方文檔: 始終以Google My Business Business Information API的官方Location資源文檔(https://developers.google.com/my-business/reference/businessinformation/rest/v1/locations)為準,了解所有可用的字段及其數據類型。這是避免readMask錯誤的根本方法。
- 精確指定: readMask參數的目的是為了請求精確的數據。只請求你確實需要的字段,這不僅能避免INVALID_ARGUMENT錯誤,還能優化api調用的性能和響應時間,減少不必要的數據傳輸。
- 嵌套字段: 對于嵌套字段(例如address對象下的locality),readMask通常只需要指定頂級字段(例如address)。API客戶端庫會自動解析并返回該對象下的所有子字段,或者文檔會明確指出如何指定嵌套路徑。在Location資源中,像address、openInfo等都是復雜對象,指定它們會返回整個對象結構。
- 錯誤處理: 在生產環境中,務必實現健壯的錯誤處理機制。捕獲并解析API返回的錯誤信息(特別是HTTP 400響應體中的fieldViolations),以便快速定位和解決問題。
總結
readMask參數在Google API中扮演著至關重要的角色,它控制著API響應中包含的數據字段。對于Google My Business Business Information API的accounts.locations.list方法,解決INVALID_ARGUMENT錯誤的關鍵在于確保readMask中指定的字段是Location資源本身定義的有效頂級屬性。通過仔細查閱API文檔并遵循正確的字段命名規范,開發者可以避免此類常見錯誤,并高效、準確地獲取所需的商家位置數據。