權限

您可以在動作中使用權限,向使用者要求個人資料,以完成要求。舉例來說,食物外送動作可以使用裝置位置存取權來要求使用者的位置資訊。

當您在動作中新增權限時,Google 助理會顯示一致的標準介面,要求使用者授予權限,以便為動作提供資訊。

可用權限

您的動作可以要求下列權限:

  • DEVICE_PRECISE_LOCATION:要求使用者的精確位置資訊 (座標和街道地址)。
  • DEVICE_COARSE_LOCATION:要求使用者的概略裝置位置 (郵遞區號和城市)。

設定權限

如要設定動作的權限,請在情境中新增運算單元類型。然後為要要求的資料權限設定運算單元。

新增權限運算單元類型

您可以授權動作透過 actions.type.Permission 運算單元類型取得使用者資訊。

如要設定這個版位類型,請按照下列步驟操作:

  1. 前往動作主控台,然後選取或建立專案。
  2. 按一下頂端選單中的「開發」
  3. 在「場景」下方,按一下您要新增權限流程的場景。
  4. 在場景的「Slot fill」部分下方,按一下 + 即可新增版位。
  5. 在「選取類型」下拉式選單中,選取 actions.type.Permission 運算單元類型。

  6. 在「輸入運算單元名稱」欄位中,為運算單元命名。

  7. 啟用「CustomSlot value writeback」,將結果寫入工作階段參數。

設定運算單元

您現在可以提供內容字串以及要授予設定運算單元的權限清單。內容字串是為何您向使用者要求資訊的理由,會在使用者要求授予動作權限時顯示。

您可以在「ConfigureSlot」(設定運算單元) 區段中設定結構定義字串和權限,如以下螢幕截圖所示:

以下程式碼片段為版位設定範例:

{
  "@type": "type.googleapis.com/google.actions.conversation.v3.PermissionValueSpec",
  "context": "Context string",
  "permissions": ["DEVICE_PRECISE_LOCATION"]
}

向使用者顯示的提示會以 "$context_string 形式顯示,請問這樣可以嗎?」

您可以使用權限代碼取得下列使用者資訊:

權限 說明
DEVICE_PRECISE_LOCATION 精確位置 (座標和街道地址)
DEVICE_COARSE_LOCATION 約略裝置位置 (郵遞區號和城市)

取得權限結果

以下各節說明如何查看權限狀態,以及在使用者授予權限後讀取使用者的資訊。

查看權限狀態

使用者授予權限時,產生的狀態會寫入與運算單元相關聯的工作階段參數。

您可以查看場景條件中的 session.params.<slot_name>.permissionStatus 值來確認權限狀態。

如要查看權限運算單元的狀態,請按照下列步驟操作:

  1. 前往「Actions 主控台」,然後按一下頂端選單中的「Develop」
  2. 在「Scenes」下方,按一下含有權限版位的場景。
  3. 在場景的「Condition」部分下方,按一下「+」新增條件。
  4. 輸入以下條件以檢查權限狀態 (其中 <slot_name> 是您在運算單元中設定的工作階段參數名稱):

    scene.slots.status == "FINAL" && (session.params.<slot_name>.permissionStatus == "PERMISSION_GRANTED" || session.params.<slot_name>.permissionStatus == "ALREADY_GRANTED")
    

  5. 在場景的「Condition」部分下方,按一下「+」新增條件。

  6. 輸入下列條件,處理使用者未同意分享個人資訊的情況:

    scene.slots.status == "FINAL"
    

  7. 在場景的「Condition」部分下方,按一下「+」新增條件。

  8. 輸入以下條件,處理使用者已授予權限而不需要再次詢問的情況:

    "DEVICE_PRECISE_LOCATION" in user.permissions
    

讀取使用者資訊

如果使用者授予權限,系統就會在後續要求中提供使用者資訊。

在下列程式碼片段中,您可以看到在向 Webhook 發出的要求中,包含的裝置位置資訊 (包含 device.currentLocation)。

要求 JSON
  {
      "handler": {
        "name": "handler"
      },
      "intent": {
        "name": "",
        "params": {
          "deviceLoc": {
            "original": "",
            "resolved": {
              "@type": "type.googleapis.com/google.actions.conversation.v3.PermissionValue",
              "permissionStatus": "PERMISSION_GRANTED",
              "grantedPermissions": [
                "DEVICE_PRECISE_LOCATION"
              ]
            }
          }
        },
        "query": "Yes"
      },
      "scene": {
        "name": "Scene",
        "slotFillingStatus": "FINAL",
        "slots": {
          "deviceLoc": {
            "mode": "REQUIRED",
            "status": "SLOT_UNSPECIFIED",
            "value": {
              "grantedPermissions": [
                "DEVICE_PRECISE_LOCATION"
              ],
              "@type": "type.googleapis.com/google.actions.conversation.v3.PermissionValue",
              "permissionStatus": "PERMISSION_GRANTED"
            },
            "updated": true
          }
        },
        "next": {
          "name": "actions.scene.END_CONVERSATION"
        }
      },
      "session": {
        "id": "session_id",
        "params": {
          "deviceLoc": {
            "grantedPermissions": [
              "DEVICE_PRECISE_LOCATION"
            ],
            "permissionStatus": "PERMISSION_GRANTED",
            "@type": "type.googleapis.com/google.actions.conversation.v3.PermissionValue"
          }
        },
        "typeOverrides": [],
        "languageCode": ""
      },
      "user": {
        "locale": "en-US",
        "params": {},
        "accountLinkingStatus": "ACCOUNT_LINKING_STATUS_UNSPECIFIED",
        "verificationStatus": "VERIFIED",
        "packageEntitlements": [],
        "permissions": [
          "DEVICE_PRECISE_LOCATION"
        ],
        "lastSeenTime": "2021-02-08T20:43:47Z"
      },
      "home": {
        "params": {}
      },
      "device": {
        "capabilities": [
          "SPEECH",
          "RICH_RESPONSE",
          "LONG_FORM_AUDIO"
        ],
        "currentLocation": {
          "coordinates": {
            "latitude": 37.422,
            "longitude": -122.084
          },
          "postalAddress": {
            "revision": 0,
            "regionCode": "US",
            "languageCode": "en",
            "postalCode": "94043",
            "sortingCode": "",
            "administrativeArea": "California",
            "locality": "Mountain View",
            "sublocality": "",
            "addressLines": ["1600 Amphitheatre Parkway"],
            "recipients": [],
            "organization": ""
          }
        }
      }
    }
    

如要進一步瞭解位置類型的結構定義,請參閱 Location 參考資料

您可以透過 Webhook 存取要求中所含的資訊,如以下程式碼片段所示:

Webhook
  app.handle('handler', (conv) => {
    let location = conv.device.currentLocation;
    conv.add(`Your postal code is ${location.postalCode}`);
  });
    

在提示中使用權限

您也可以在靜態提示中參照權限。舉例來說,針對裝置位置,您可以使用 $device.currentLocation.coordinates.*$device.currentLocation.postalAddress.*。下列程式碼片段說明如何在提示中參照使用者的城市:

candidates:
  - first_simple:
      variants:
        - speech: >-
            There are no events scheduled tomorrow in the city of $device.currentLocation.postalAddress.locality.