本文旨在解決在使用 Google My Business Business Information API 的 accounts.locations.list 方法時,因 readMask 參數不正確導致 INVALID_ARGUMENT 錯誤的常見問題。我們將深入分析錯誤原因,明確指出 readMask 必須指定 Location 資源本身的有效屬性,而非其他關聯實體字段。通過提供正確的參數使用方法和示例代碼,幫助開發者順利獲取所需的商家位置信息,避免不必要的api調用失敗。
隨著 google my business api 舊版本的逐步棄用,開發者需要遷移到新的 api 服務,例如 google_service_mybusinessbusinessinformation 來管理商家位置信息。在進行位置列表查詢時,readmask 參數是一個關鍵的字段,它允許開發者指定希望在響應中返回的特定字段,從而優化數據傳輸和處理效率。然而,不正確的 readmask 值常常導致 http 400 invalid_argument 錯誤。
診斷 readMask 錯誤:INVALID_ARGUMENT
當您嘗試使用 Google_Service_MyBusinessBusinessInformation 服務的 accounts.locations.list 方法,并傳入一個無效的 readMask 時,API 會返回一個典型的 GoogleServiceException #400 錯誤,其詳細信息如下:
{ "error": { "code": 400, "message": "Request contains an invalid argument.", "status": "INVALID_ARGUMENT", "details": [ { "@type": "type.googleapis.com/google.rpc.BadRequest", "fieldViolations": [ { "field": "read_mask", "description": "Invalid field mask provided" } ] } ] } }
這個錯誤明確指出 read_mask 字段存在問題,即提供了“無效的字段掩碼”。問題通常在于 readMask 中包含了不屬于 Location 資源本身的屬性,或者屬性名稱拼寫錯誤。例如,嘗試獲取 user.display_name 這樣的字段,它并非 Location 資源的標準屬性。
核心問題:readMask 參數的正確使用
readMask 參數的作用是告訴 API 您需要響應中包含哪些特定的字段。對于 accounts.locations.list 方法,readMask 中的字段必須是 Location 資源(Google_Service_MyBusinessBusinessInformation_Location 對象)的有效屬性。這意味著您不能隨意指定任何與位置相關的字段,而必須參照 Google My Business Business Information API v1 文檔中 Location 資源的定義。
常見的錯誤是將其他服務或關聯實體(如用戶賬戶)的字段混入 Location 的 readMask 中。例如,user.display_name 顯然不屬于 Location 資源,因此會導致 INVALID_ARGUMENT 錯誤。即使是 photo 這樣的字段,雖然 Location 資源中包含照片信息,但其具體的引用方式也需符合API規范,通常是直接指定 photos 字段以獲取照片列表或相關元數據。
有效的 Location 資源屬性示例包括:
- name:位置的資源名稱。
- title:商家名稱。
- websiteUri:商家網站的URI。
- address:商家地址。
- latlng:經緯度。
- primaryCategory:主要業務類別。
- phoneNumbers:電話號碼。
- openInfo:營業狀態信息。
- photos:照片信息(如果需要獲取照片詳情,可能需要進一步的API調用或特定的字段組合)。
- metadata:元數據。
- storeCode:商家自定義的店鋪代碼。
請務必查閱官方文檔: Google My Business Business Information API v1 Location 資源: https://www.php.cn/link/dc8ea2d055557e14585d74fc6c1033b2
解決方案與示例代碼
解決 readMask 錯誤的關鍵在于確保 readMask 中只包含 Location 資源中定義的有效屬性。以下是修正后的 php 代碼示例,展示了如何正確構造 readMask:
<?php // 假設 $client 已經是一個經過認證的 Google_Client 實例 // 并且已經包含了 Google My Business API 相關的服務類 // 1. 初始化 My Business Account Management 服務以獲取賬戶信息 $my_business_account = new Google_Service_MyBusinessAccountManagement($client); $list_accounts_response = $my_business_account->accounts->listAccounts(); // 確保至少有一個賬戶 if (empty($list_accounts_response)) { die("No Google My Business accounts found."); } // 獲取第一個賬戶的名稱,通常用于后續API調用 $account = $list_accounts_response[0]; $accountName = $account->name; // 例如:accounts/1234567890 // 2. 初始化 My Business Business Information 服務 $mybusinessService = new Google_Service_MyBusinessBusinessInformation($client); $locationsService = $mybusinessService->accounts_locations; // 3. 定義正確的 queryParams,特別是 readMask // readMask 必須包含 Location 資源中定義的有效字段 $queryParams = [ "pageSize" => 10, // 正確的 readMask 示例:只請求 Location 資源中的 'name', 'title' 和 'websiteUri' 字段 'readMask' => "name,title,websiteUri,address,primaryCategory,phoneNumbers" // 如果需要照片信息,通常直接指定 'photos' 字段,但獲取詳細照片URL可能需要額外的API調用或在photos字段中包含子字段 // 'readMask' => "name,title,photos" // 示例:請求名稱、標題和照片信息 ]; try { // 4. 調用 listAccountsLocations 方法獲取位置列表 $locationsList = $locationsService->listAccountsLocations($accountName, $queryParams); // 遍歷并打印獲取到的位置信息 if ($locationsList->getLocations()) { echo "Successfully retrieved locations:n"; foreach ($locationsList->getLocations() as $location) { echo " Location Name: " . $location->getName() . "n"; echo " Location Title: " . $location->getTitle() . "n"; echo " Website URI: " . $location->getWebsiteUri() . "n"; // 訪問其他字段,例如地址 if ($location->getAddress()) { echo " Address: " . $location->getAddress()->getPostalAddress()->getLocality() . ", " . $location->getAddress()->getPostalAddress()->getRegionCode() . "n"; } echo "---n"; } } else { echo "No locations found for this account.n"; } } catch (GoogleServiceException $e) { // 捕獲并處理 API 錯誤 echo "An error occurred: " . $e->getMessage() . "n"; echo "Error details: " . $e->getErrors()[0]['message'] . "n"; if (isset($e->getErrors()[0]['details'][0]['fieldViolations'])) { foreach ($e->getErrors()[0]['details'][0]['fieldViolations'] as $violation) { echo " Field Violation: " . $violation['field'] . " - " . $violation['description'] . "n"; } } } catch (Exception $e) { // 捕獲其他通用錯誤 echo "An unexpected error occurred: " . $e->getMessage() . "n"; } ?>
在上述代碼中,’readMask’ => “name,title,websiteUri,address,primaryCategory,phoneNumbers” 是一個有效的示例。它僅請求 Location 資源中明確定義的字段,從而避免了 INVALID_ARGUMENT 錯誤。
重要注意事項
- 查閱官方文檔是關鍵: 始終以 Google API 的官方文檔為準,特別是關于特定資源(如 Location)的字段定義。這是確保 readMask 參數正確性的最可靠方法。
- 按需請求字段: 僅在 readMask 中指定您實際需要的字段。這不僅能減少API響應的大小,降低網絡延遲,還能提高API調用的效率和性能。請求不必要的字段會浪費資源。
- 錯誤處理: 在您的代碼中實現健壯的錯誤處理機制。捕獲 GoogleServiceException 可以幫助您診斷和處理 API 返回的特定錯誤,例如 INVALID_ARGUMENT。
- API 憑證和權限: 確保您的 Google Cloud 項目已啟用 Google My Business API,并且您的服務賬戶或OAuth 2.0 憑證擁有足夠的權限來訪問 My Business 賬戶和位置信息。
總結
readMask 參數在 Google My Business Business Information API 中是一個強大的工具,用于精細控制 API 響應中返回的數據。解決 INVALID_ARGUMENT 錯誤的關鍵在于理解 readMask 必須引用目標資源(在本例中是 Location)的有效、直接的屬性。通過仔細查閱 API 文檔并遵循示例代碼中的最佳實踐,您可以有效地利用 readMask 來優化您的 API 集成,確保順利獲取所需的商家位置數據。