Alexa-Skills-kit:如何在 alexa 会话之外获取用户有权使用的技能产品

Alexa-Skills-kit: How do a get the in-skill-products a user is entitled to outside of an alexa session

我有一个 Alexa-Skill 并且正在为此技能构建一个 Web 应用程序。在技​​能中,用户可以为 ISP 购买订阅,在 Web 应用程序中,我需要知道用户是否订阅(有权)该 ISP。我该怎么做,甚至可能吗?

更多信息

我的想法

到目前为止我尝试了什么

首先,我尝试通过 ask-sdk 调用我的技能的 lambda 函数,并请求我的技能的“getEntitledProducts”Intent。此意图将授权产品存储在响应的 sessionAttributes 中。 我从 alexa 开发人员控制台测试选项卡收到的请求,我在其中(成功)调用了上述意图。在开发者控制台中,它可以正常工作

request = {
  "version": "1.0",
    "session": {
        "new": True,
        "sessionId": "<same session id as in the request in the alexa developer console>",
        "application": {
            "applicationId": "<my-application-id>"
        },
        "user": {
            "userId": "<the userId i want the entitled products for>"
        }
    },
    "context": {
      "System": {
            "application": {
                "applicationId": "<my-application-id>"
            },
            "user": {
                "userId": "<the userId i want the entitled products for>"
            },
            "device": {
                "deviceId": "<same device id as in the request in the alexa developer console>",
                "supportedInterfaces": {}
            },
            "apiEndpoint": "https://api.eu.amazonalexa.com",
            "apiAccessToken": "<same token as in the request in the alexa developer console>"
        }
    },
    "request": {
        "type": "IntentRequest",
        "requestId": "<same request id as in the request in the alexa developer console>",
        "locale": "de-DE",
        "timestamp": "2021-05-07T18:40:53Z",
        "intent": {
            "name": "getEntitledProducts",
            "confirmationStatus": "NONE"
        },
        "dialogState": "STARTED"
    }
}

此“getEntitledProducts”意图使用 monetization_service 检索用户的 ISP 状态:

locale = handler_input.request_envelope.request.locale
ms = handler_input.service_client_factory.get_monetization_service()
product_response = ms.get_in_skill_products(locale)

最后一行出现以下错误:

The authentication token is invalid or doesn't have access to make this request

我明白为什么身份验证可能不起作用,因为我只是从开发人员控制台复制了整个请求。我怀疑 version.session.sessionIdcontext.System.apiAccessToken 无效(现在?)。但是如何在技能会话之外使用 ask-sdk 获得正确的访问令牌?


接下来,我尝试在我的 Web 应用程序代码中直接使用 ask-sdk monetization_service,如下所示:

from ask_sdk_core.api_client import DefaultApiClient
from ask_sdk_model.services.service_client_factory import ServiceClientFactory
from ask_sdk_model.services.api_configuration import ApiConfiguration
    
fac = ServiceClientFactory(ApiConfiguration(DefaultApiClient()))
ms = fac.get_monetization_service()
ms.get_in_skill_products("de-DE")

这里我得到以下错误:

TypeError: must be str, not NoneType

因为我没有向 ApiConfiguration 提供“authorization_value”。但是我如何获得这样的授权值呢?

我尝试按照 here 所述使用 LwaClient,但在这里我什至不知道在 LwaClient.get_access_token_for_scope(scope) 的调用中使用什么作为“范围”(他们使用“alexa” :abc" 在示例中)。我猜 LwaClient 用于完全不同的东西(帐户链接)。


在这一点上,我花了大约 8 个小时寻找一种方法来查明用户是否订阅了 ISP,但我觉得我没有更接近解决方案。

当然我可以在每次用户使用该技能时更新技能数据库中的“is_subscribed”值,但是如果用户有一段时间不使用该技能怎么办。然后这个值永远不会更新,我的网络应用程序永远不会知道用户是否仍然订阅。

希望有人能帮助我。我从来没有对一个编程问题感到如此绝望,因为这是我第一次使用 Google 和 Whosebug 找不到解决方案。

一种可能但不是最佳的方法是您建议的数据库解决方案,但需要一些额外的数据。当用户第一次订阅时,您始终可以在数据库中保存订阅日期时间,并且您知道订阅​​的有效期。然后你只需要玩 datetime 库就可以知道用户是否订阅了。

如果您的技能已经 运行 并且已经上线,这将无济于事,但如果不是,那么这会有帮助。

我在 Amazon developer forum 上得到了这个问题的答案。 目前无法在技能会话之外调用货币化服务。