【问题标题】:Alexa-Skills-kit: How do a get the in-skill-products a user is entitled to outside of an alexa sessionAlexa-Skills-kit:如何在 Alexa 会话之外获得用户有权使用的技能产品
【发布时间】:2021-05-08 13:20:57
【问题描述】:

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

更多信息

  • 我的技能代码(使用 Alexa-Skills-Kit 开发工具包以 python 编写)托管为 AWS Lambda 函数。
  • 技能的数据库作为 AWS DynamoDB。我正在开发的 Web 应用可以访问该 DynamoDB。

我的想法

到目前为止我尝试了什么

首先,我尝试通过 ask-sdk 调用我的技能的 lambda 函数,并请求我的技能的“getEntitledProducts”意图。此意图将授权产品存储在响应的 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)

最后一行是我得到以下错误的地方:

身份验证令牌无效或无权发出此请求

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


接下来我尝试直接在我的 Web-App 代码中使用 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 提供“授权值”。但是如何获得这样的授权值呢?

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


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

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

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

【问题讨论】:

    标签: python amazon-web-services alexa alexa-skills-kit


    【解决方案1】:

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

    如果您的技能已经在运行并且是实时的,这将没有帮助,但如果没有,那么这会有所帮助。

    【讨论】:

    • 感谢您的回答。您是否确定,没有办法在 alexa 技能之外(在我的 Web 应用程序中)获得权利状态?关于您的建议:您的意思是只保存用户首次购买订阅的日期,然后添加 30 天作为结束时间?但是如果订阅持续几个月,我不会知道新的结束时间,对吧?我觉得如果仍然有权添加 30 天,一段时间后最终会变得不太准确。另外,我可能不知道如果用户在技能之外完成了订阅,是否取消了订阅,对吧?
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-14
      • 1970-01-01
      • 2016-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-27
      • 2015-09-15
      相关资源
      最近更新 更多