在Python中为Alexa技能添加会话属性

时间:2017-03-24 06:04:09

标签: python json aws-lambda alexa alexa-skill

我的意图架构中有3个插槽(dollar_valuerecipient_firstdef create_dollar_value_attribute(dollar_value): return {"dollar_value": dollar_value} def create_account_attribute(account): return {"account": account} def create_recipient_first_attribute(recipient_first): return {"recipient_first": recipient_first} ),用于Alexa技能,我想在会话属性中保存扬声器提供的任何插槽

我使用以下方法设置会话属性:

sessionAttributes

但是,正如您可能猜到的那样,如果我想在sessionAttributes中保存多个广告位作为数据,则会覆盖session_attributes = {} if session.get('attributes', {}) and "recipient_first" not in session.get('attributes', {}): recipient_first = intent['slots']['recipient_first']['value'] session_attributes = create_recipient_first_attribute(recipient_first) if session.get('attributes', {}) and "dollar_value" not in session.get('attributes', {}): dollar_value = intent['slots']['dollar_value']['value'] session_attributes = create_dollar_value_attribute(dollar_value) ,如下所示:

dollar_value

我的lambda函数对语音输入的JSON响应,其中提供了两个插槽(recipient_firstthe create_dollar_value_attribute)如下(我的猜测是第二个{ "version": "1.0", "response": { "outputSpeech": { "type": "PlainText", "text": "Some text output" }, "card": { "content": "SessionSpeechlet - Some text output", "title": "SessionSpeechlet - Send Money", "type": "Simple" }, "reprompt": { "outputSpeech": { "type": "PlainText" } }, "shouldEndSession": false }, "sessionAttributes": { "dollar_value": "30" } } 方法if语句覆盖第一个):

sessionAttributes

"sessionAttributes": { "dollar_value": "30", "recipient_first": "Some Name" }, 的正确答案应为:

sessionAttributes

如何创建此回复?有没有更好的方法在JSON响应中向ERROR: Command Invocation failure: failed to repackage resources. CommandInvokationFailure: Failed to re-package resources. /Users/pb036local/Desktop/build-tools/25.0.2/aapt package --auto-add-overlay -v -f -m -J gen -M AndroidManifest.xml -S "res" -I "/Users/pb036local/Desktop/platforms/android-25/android.jar" -F bin/resources.ap_ --extra-packages android.support.graphics.drawable.animated:android.support.v7.appcompat:android.support.v7.cardview:android.support.customtabs:com.facebook:com.facebook.android:android.support.v4:android.support.graphics.drawable -S " 添加值?

5 个答案:

答案 0 :(得分:3)

在我看来,用Python添加sessionAttributes的最简单方法似乎是使用字典。例如,如果要在会话属性中存储以后的某些插槽:

session['attributes']['slotKey'] = intent['slots']['slotKey']['value']

接下来,您可以将其传递给构建响应方法:

buildResponse(session['attributes'], buildSpeechletResponse(title, output, reprompt, should_end_session))

在这种情况下的实施:

def buildSpeechletResponse(title, output, reprompt_text, should_end_session):
return {
    'outputSpeech': {
        'type': 'PlainText',
        'text': output
    },
    'card': {
        'type': 'Simple',
        'title': "SessionSpeechlet - " + title,
        'content': "SessionSpeechlet - " + output
    },
    'reprompt': {
        'outputSpeech': {
            'type': 'PlainText',
            'text': reprompt_text
        }
    },
    'shouldEndSession': should_end_session
    }


def buildResponse(session_attributes, speechlet_response):
    return {
        'version': '1.0',
        'sessionAttributes': session_attributes,
        'response': speechlet_response
    }

这将在Lambda响应JSON中以推荐的方式创建sessionAttributes。

如果不存在,只添加新的sessionAttribute不会覆盖最后一个sessionAttribute。它只会创建一个新的键值对。

请注意,这可能在服务模拟器中运行良好,但在实际的Amazon Echo上进行测试时可能会返回键属性错误。根据这个post

在服务模拟器上,会话以Session开始:{... Attributes:{},...} 当会话在Echo上开始时,Session根本没有Attributes键。

我解决这个问题的方法是只要在创建新会话时在lambda处理程序中手动创建它:

 if event['session']['new']:
    event['session']['attributes'] = {}
    onSessionStarted( {'requestId': event['request']['requestId'] }, event['session'])
if event['request']['type'] == 'IntentRequest':
    return onIntent(event['request'], event['session'])

答案 1 :(得分:1)

首先,您必须定义session_attributes。

session_attributes = {}

然后而不是使用

session_attributes = create_recipient_first_attribute(recipient_first)

你应该使用

session_attributes.update(create_recipient_first_attribute(recipient_first))

您面临的问题是因为您正在重新分配session_attributes。而不是这个,你应该只更新session_attributes。

所以你的最终代码将成为:

session_attributes = {}
if session.get('attributes', {}) and "recipient_first" not in session.get('attributes', {}):
    recipient_first = intent['slots']['recipient_first']['value']
    session_attributes.update(create_recipient_first_attribute(recipient_first))
if session.get('attributes', {}) and "dollar_value" not in session.get('attributes', {}):
    dollar_value = intent['slots']['dollar_value']['value']
    session_attributes.update(create_dollar_value_attribute(dollar_value))

答案 2 :(得分:0)

ASK SDK for Python提供了一个attribute manager,以管理技能中的请求/会话/持久性级别属性。您可以查看color picker sample,了解如何在技能开发中使用这些属性。

答案 3 :(得分:0)

看看下面的内容:

account = intent['slots']['account']['value'] 
dollar_value = intent['slots']['dollar_value']['value'] 
recipient_first = intent['slots']['recipient_first']['value']  

# put your data in a dictionary
attributes = { 
    'account':account, 
    'dollar_value':dollar_value, 
    'recipient_first':recipient_first
}

在响应中的 'sessionAttributes' 中放入 属性 词典。 Alexa回复您后,您应该在 'sessionAttributes' 中找回它。

希望这会有所帮助。

答案 4 :(得分:0)

以下代码片段还将防止覆盖会话属性:

session_attributes = session.get('attributes', {})

if "recipient_first" not in session_attributes:
    session_attributes['recipient_first'] = intent['slots']['recipient_first']['value']

if "dollar_value" not in session_attributes:
    session_attributes['dollar_value'] =  = intent['slots']['dollar_value']['value']