在 Python 中为 Alexa 技能添加会话属性
Adding session attributes in Python for Alexa skills
我的 Alexa 技能意图模式中有 3 个槽位(account
、dollar_value
、recipient_first
),我想保存演讲者提供的任何槽位会话属性。
我正在使用以下方法设置会话属性:
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 函数对提供了两个插槽(dollar_value
和 recipient_first
)的语音输入的 JSON 响应如下(我的猜测是 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
添加值是否有更好的方法?
在我看来,添加 sessionAttributes
和 Python 的最简单方法似乎是使用字典。例如,如果你想在会话属性中存储一些未来的插槽:
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 响应中以推荐的方式创建 sessionAttributes JSON。
此外,仅添加一个新的 sessionAttribute 不会覆盖最后一个不存在的属性。它只会创建一个新的键值对。
请注意,这在服务模拟器中可能运行良好,但在实际 Amazon Echo 上测试时可能 return 出现关键属性错误。根据这个post,
在 Service Simulator 上,会话以 Session:{ ... Attributes:{}, ... } 开头
当会话在 Echo 上启动时,会话根本没有属性键。
我解决这个问题的方法是在创建新会话时在 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'])
首先,您必须定义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))
ASK SDK for Python provides an attribute manager, to manage request/session/persistence level attributes in the skill. You can look at the color picker sample,看看如何在技能开发中使用这些属性。
看看下面的内容:
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
}
将 attributes 字典放入 'sessionAttributes' 在您的回复中。一旦 Alexa 回复您,您应该在 'sessionAttributes' 取回它。
希望对您有所帮助。
以下代码片段也将防止覆盖会话属性:
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']
我的 Alexa 技能意图模式中有 3 个槽位(account
、dollar_value
、recipient_first
),我想保存演讲者提供的任何槽位会话属性。
我正在使用以下方法设置会话属性:
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 函数对提供了两个插槽(dollar_value
和 recipient_first
)的语音输入的 JSON 响应如下(我的猜测是 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
添加值是否有更好的方法?
在我看来,添加 sessionAttributes
和 Python 的最简单方法似乎是使用字典。例如,如果你想在会话属性中存储一些未来的插槽:
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 响应中以推荐的方式创建 sessionAttributes JSON。
此外,仅添加一个新的 sessionAttribute 不会覆盖最后一个不存在的属性。它只会创建一个新的键值对。
请注意,这在服务模拟器中可能运行良好,但在实际 Amazon Echo 上测试时可能 return 出现关键属性错误。根据这个post,
在 Service Simulator 上,会话以 Session:{ ... Attributes:{}, ... } 开头 当会话在 Echo 上启动时,会话根本没有属性键。
我解决这个问题的方法是在创建新会话时在 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'])
首先,您必须定义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))
ASK SDK for Python provides an attribute manager, to manage request/session/persistence level attributes in the skill. You can look at the color picker sample,看看如何在技能开发中使用这些属性。
看看下面的内容:
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
}
将 attributes 字典放入 'sessionAttributes' 在您的回复中。一旦 Alexa 回复您,您应该在 'sessionAttributes' 取回它。
希望对您有所帮助。
以下代码片段也将防止覆盖会话属性:
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']