2017-03-24 47 views
1

我在我的意图模式中有3个插槽(account,dollar_value,,0 )用于Alexa技能,我想保存讲话者在会话属性中提供的任何插槽。在Python中为Alexa技能添加会话属性

我使用下面的方法来设置会话属性:

def 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} 

但是,如你所猜测的,如果我想保存多个插槽数据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) 

从我lambda函数的JSON响应对于其中两个时隙(dollar_valuerecipient_first)中提供的是如下语音输入(我的猜测是,the create_dollar_value_attribute方法在第二if语句覆盖第一):

{ 
    "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" 
    } 
} 

sessionAttributes正确的反应应该是:

"sessionAttributes": { 
    "dollar_value": "30", 
    "recipient_first": "Some Name" 
    }, 

如何创建对此有何反应?有没有更好的方法在JSON响应中为sessionAttributes添加值?

回答

2

在我看来,用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不会覆盖最后一个,如果它不存在。它只会创建一个新的键值对。

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

在服务模拟器上,会话以会话开始:{...属性:{},...} 当会话在Echo上启动时,会话根本没有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']) 
+0

我没有在'事件属性[“会议”]'但是我不知道如何实例化这个'事件[“会议”] [”属性'] = {}'会解决它? alexa/lambda如何知道? 'onSessionStarted'函数做了什么? – Jonathan

0

首先,你必须定义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))