如果您使用的是 Amazon Lex V2,请改为参阅 Amazon Lex V2 指南。
如果您使用的是 Amazon Lex V1,我们建议您将机器人升级到 Amazon Lex V2。我们不再向 V1 添加新功能,强烈建议使用 V2 以获得全新的机器人。
本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
信息流详细信息
ScheduleAppointment
自动程序蓝图主要展示动态生成的响应卡的用法。本练习中的 Lambda 函数将在其发送给 Amazon Lex 的响应中包含响应卡。Amazon Lex 将在其发送给客户端的回复中包含响应卡。本部分介绍了以下两点:
-
客户端和 Amazon Lex 之间的数据流。
本节假设客户使用
PostText
运行时向 Amazon Lex 发送请求,API并相应地显示请求/响应详情。有关PostText
运行时的更多信息API,请参阅PostText。注意
有关客户与 Amazon Lex 之间信息流的示例,其中客户使用
PostContent
API,请参阅步骤 2a (可选):查看语音信息流的详细信息 (控制台) 。 -
Amazon Lex 和 Lambda 函数之间的数据流。有关更多信息,请参阅 Lambda 函数输入事件和响应格式。
注意
此示例假定您正在使用 Facebook Messenger 客户端,该客户端不会将请求中的会话属性传递给 Amazon Lex。因此,本部分中的示例请求显示为空 sessionAttributes
。如果您使用 Amazon Lex 控制台提供的客户端测试机器人,则客户端将包含这些会话属性。
本部分描述了每个用户输入后会发生的情况。
-
用户:类型
Book an appointment
。-
客户端 (控制台) 将向 Amazon Lex 发送以下 PostContent 请求:
POST /bot/
ScheduleAppointment
/alias/$LATEST
/user/bijt6rovckwecnzesbthrr1d7lv3ja3n
/text "Content-Type":"application/json" "Content-Encoding":"amz-1.0" { "inputText":"book appointment", "sessionAttributes":{} }请求URI和正文都向 Amazon Lex 提供了信息:
-
请求 URI-提供机器人名称 (ScheduleAppointment)、机器人别名 ($LATEST) 和用户名 ID。尾部
text
表示这是一个PostText
(不是PostContent
)API请求。 -
请求正文 – 包括用户输入 (
inputText
) 和空sessionAttributes
。
-
-
在
inputText
中,Amazon Lex 可检测意图 (MakeAppointment
)。该服务将调用 Lambda 函数(配置为代码挂钩),以通过传递以下事件执行初始化和验证。有关详细信息,请参阅输入事件格式。{ "currentIntent": { "slots": { "AppointmentType": null, "Date": null, "Time": null }, "name": "MakeAppointment", "confirmationStatus": "None" }, "bot": { "alias": null, "version": "$LATEST", "name": "ScheduleAppointment" }, "userId": "bijt6rovckwecnzesbthrr1d7lv3ja3n", "invocationSource": "DialogCodeHook", "outputDialogMode": "Text", "messageVersion": "1.0", "sessionAttributes": {} }
除了客户端发送的信息以外,Amazon Lex 还包含以下数据:
-
currentIntent
– 提供当前的目的信息。 -
invocationSource
— 表明 Lambda 函数调用的目的。在本例中,目的是执行用户数据初始化和验证。(Amazon Lex 知道用户尚未提供所有插槽数据来履行意图。) -
messageVersion
— Amazon Lex 当前只支持 1.0 版。
-
-
此时,所有槽值均为空值 (没有需要验证的内容)。Lambda 函数会向 Amazon Lex 返回以下响应,以指示服务引发
AppointmentType
插槽的信息。有关响应格式的信息,请参阅 响应格式。{ "dialogAction": { "slotToElicit": "AppointmentType", "intentName": "MakeAppointment", "responseCard": { "genericAttachments": [ { "buttons": [ { "text": "cleaning (30 min)", "value": "cleaning" }, { "text": "root canal (60 min)", "value": "root canal" }, { "text": "whitening (30 min)", "value": "whitening" } ], "subTitle": "What type of appointment would you like to schedule?", "title": "Specify Appointment Type" } ], "version": 1, "contentType": "application/vnd.amazonaws.card.generic" }, "slots": { "AppointmentType": null, "Date": null, "Time": null }, "type": "ElicitSlot", "message": { "content": "What type of appointment would you like to schedule?", "contentType": "PlainText" } }, "sessionAttributes": {} }
响应包含
dialogAction
和sessionAttributes
字段。此外,dialogAction
字段将返回以下字段:-
type
— 通过将此字段设置为ElicitSlot
,Lambda 函数将指示 Amazon Lex 引发slotToElicit
字段中指定的插槽的值。Lambda 函数还将提供要传达给用户的message
。 -
responseCard
— 标识AppointmentType
插槽的可能值列表。支持响应卡的客户端(如 Facebook Messenger)将显示响应卡,以允许用户选择一个预约类型,如下图所示:
-
-
如来自 Lambda 函数的响应中的
dialogAction.type
所示,Amazon Lex 会将以下响应发送回客户端:客户端将读取响应,然后显示消息:“您想要安排哪种类型的预约?” 以及响应卡 (如果客户端支持响应卡)。
-
-
用户:根据客户端,用户有两个选项:
-
如果显示响应卡,则选择 root canal (60 min) 或键入
root canal
。 -
如果客户端不支持响应卡,则键入
root canal
。
-
客户端将向 Amazon Lex 发送以下
PostText
请求(我们添加了换行符以便于阅读):POST /bot/
BookTrip
/alias/$LATEST
/user/bijt6rovckwecnzesbthrr1d7lv3ja3n
/text "Content-Type":"application/json" "Content-Encoding":"amz-1.0" { "inputText": "root canal", "sessionAttributes": {} } -
Amazon Lex 将调用 Lambda 函数,以通过发送以下事件作为参数来验证用户数据:
{ "currentIntent": { "slots": { "AppointmentType": "root canal", "Date": null, "Time": null }, "name": "MakeAppointment", "confirmationStatus": "None" }, "bot": { "alias": null, "version": "$LATEST", "name": "ScheduleAppointment" }, "userId": "bijt6rovckwecnzesbthrr1d7lv3ja3n", "invocationSource": "DialogCodeHook", "outputDialogMode": "Text", "messageVersion": "1.0", "sessionAttributes": {} }
在事件数据中,请注意以下事项:
-
invocationSource
仍然是DialogCodeHook
。在此步骤中,我们只验证用户数据。 -
Amazon Lex 会将
AppointmentType
插槽中的currentIntent.slots
字段设置为root canal
。 -
Amazon Lex 将仅在客户端和 Lambda 函数之间传递
sessionAttributes
字段。
-
-
Lambda 函数将验证用户输入并向 Amazon Lex 返回以下响应,指示服务引发预约日期的值。
{ "dialogAction": { "slotToElicit": "Date", "intentName": "MakeAppointment", "responseCard": { "genericAttachments": [ { "buttons": [ { "text": "2-15 (Wed)", "value": "Wednesday, February 15, 2017" }, { "text": "2-16 (Thu)", "value": "Thursday, February 16, 2017" }, { "text": "2-17 (Fri)", "value": "Friday, February 17, 2017" }, { "text": "2-20 (Mon)", "value": "Monday, February 20, 2017" }, { "text": "2-21 (Tue)", "value": "Tuesday, February 21, 2017" } ], "subTitle": "When would you like to schedule your root canal?", "title": "Specify Date" } ], "version": 1, "contentType": "application/vnd.amazonaws.card.generic" }, "slots": { "AppointmentType": "root canal", "Date": null, "Time": null }, "type": "ElicitSlot", "message": { "content": "When would you like to schedule your root canal?", "contentType": "PlainText" } }, "sessionAttributes": {} }
同样,响应包含
dialogAction
和sessionAttributes
字段。此外,dialogAction
字段将返回以下字段:-
type
— 通过将此字段设置为ElicitSlot
,Lambda 函数将指示 Amazon Lex 引发slotToElicit
字段中指定的插槽的值。Lambda 函数还将提供要传达给用户的message
。 -
responseCard
— 标识Date
插槽的可能值列表。支持响应卡的客户端 (如 Facebook Messenger) 将显示响应卡,以允许用户选择一个预约日期,如下图所示:尽管 Lambda 函数返回了五个日期,但客户端 (Facebook Messenger) 对于一张响应卡只能使用三个按钮。因此,您只能在屏幕截图中看到前三个值。
这些日期在 Lambda 函数中是硬编码值。在生产应用程序中,您可以使用日历实时获得可用的日期。由于日期是动态的,因此您必须使用 Lambda 函数动态生成响应卡。
-
-
Amazon Lex 将注意到
dialogAction.type
并向客户端返回以下响应,其中包括来自 Lambda 函数的响应中的信息。客户端将显示消息:When would you like to schedule your root canal? 以及响应卡(如果客户端支持响应卡)。
-
-
用户:类型
Thursday
。-
客户端将向 Amazon Lex 发送以下
PostText
请求(我们添加了换行符以便于阅读):POST /bot/
BookTrip
/alias/$LATEST
/user/bijt6rovckwecnzesbthrr1d7lv3ja3n
/text "Content-Type":"application/json" "Content-Encoding":"amz-1.0" { "inputText": "Thursday", "sessionAttributes": {} } -
Amazon Lex 将调用 Lambda 函数,以通过发送以下事件作为参数来验证用户数据:
{ "currentIntent": { "slots": { "AppointmentType": "root canal", "Date": "2017-02-16", "Time": null }, "name": "MakeAppointment", "confirmationStatus": "None" }, "bot": { "alias": null, "version": "$LATEST", "name": "ScheduleAppointment" }, "userId": "u3fpr9gghj02zts7y5tpq5mm4din2xqy", "invocationSource": "DialogCodeHook", "outputDialogMode": "Text", "messageVersion": "1.0", "sessionAttributes": {} }
在事件数据中,请注意以下事项:
-
invocationSource
仍然是DialogCodeHook
。在此步骤中,我们只验证用户数据。 -
Amazon Lex 会将
Date
插槽中的currentIntent.slots
字段设置为2017-02-16
。 -
Amazon Lex 将仅在客户端和 Lambda 函数之间传递
sessionAttributes
。
-
-
Lambda 函数将验证用户输入。此时,Lambda 函数将确定指定日期没有可用的预约。然后,它将向 Amazon Lex 返回以下响应,指示服务再次引发预约日期的值。
{ "dialogAction": { "slotToElicit": "Date", "intentName": "MakeAppointment", "responseCard": { "genericAttachments": [ { "buttons": [ { "text": "2-15 (Wed)", "value": "Wednesday, February 15, 2017" }, { "text": "2-17 (Fri)", "value": "Friday, February 17, 2017" }, { "text": "2-20 (Mon)", "value": "Monday, February 20, 2017" }, { "text": "2-21 (Tue)", "value": "Tuesday, February 21, 2017" } ], "subTitle": "When would you like to schedule your root canal?", "title": "Specify Date" } ], "version": 1, "contentType": "application/vnd.amazonaws.card.generic" }, "slots": { "AppointmentType": "root canal", "Date": null, "Time": null }, "type": "ElicitSlot", "message": { "content": "We do not have any availability on that date, is there another day which works for you?", "contentType": "PlainText" } }, "sessionAttributes": { "bookingMap": "{\"2017-02-16\": []}" } }
同样,响应包含
dialogAction
和sessionAttributes
字段。此外,dialogAction
将返回以下字段:-
dialogAction
字段:-
type
— Lambda 函数将此值设置为ElicitSlot
并将slotToElicit
字段重置为Date
。Lambda 函数还将提供要传达给用户的相应message
。 -
responseCard
– 返回Date
槽的值列表。
-
-
sessionAttributes
— 此时,Lambda 函数包含bookingMap
会话属性。其值就是预约的请求日期和可用预约 (空对象表示无可用预约)。
-
-
Amazon Lex 将注意到
dialogAction.type
并向客户端返回以下响应,其中包括来自 Lambda 函数的响应中的信息。客户端将显示消息:We do not have any availability on that date, is there another day which works for you? 以及响应卡(如果客户端支持响应卡)。
-
-
用户:根据客户端,用户有两个选项:
-
如果显示响应卡,则选择 2-15 (Wed) 或键入
Wednesday
。 -
如果客户端不支持响应卡,则键入
Wednesday
。
-
客户端将向 Amazon Lex 发送以下
PostText
请求:POST /bot/
BookTrip
/alias/$LATEST
/user/bijt6rovckwecnzesbthrr1d7lv3ja3n
/text "Content-Type":"application/json" "Content-Encoding":"amz-1.0" { "inputText": "Wednesday", "sessionAttributes": { } }注意
Facebook Messenger 客户端不设置任何会话属性。如果您要维护请求之间的会话状态,必须使用 Lambda 函数完成操作。在实际应用程序中,您可以在后端数据库中维护这些会话属性。
-
Amazon Lex 将调用 Lambda 函数,以通过发送以下事件作为参数来验证用户数据:
{ "currentIntent": { "slots": { "AppointmentType": "root canal", "Date": "2017-02-15", "Time": null }, "name": "MakeAppointment", "confirmationStatus": "None" }, "bot": { "alias": null, "version": "$LATEST", "name": "ScheduleAppointment" }, "userId": "u3fpr9gghj02zts7y5tpq5mm4din2xqy", "invocationSource": "DialogCodeHook", "outputDialogMode": "Text", "messageVersion": "1.0", "sessionAttributes": { } }
Amazon Lex 通过将
Date
插槽设置为2017-02-15
更新了currentIntent.slots
。 -
Lambda 函数将验证用户输入并向 Amazon Lex 返回以下响应,从而指示服务引发预约时间的值。
{ "dialogAction": { "slots": { "AppointmentType": "root canal", "Date": "2017-02-15", "Time": "16:00" }, "message": { "content": "What time on 2017-02-15 works for you? 4:00 p.m. is our only availability, does that work for you?", "contentType": "PlainText" }, "type": "ConfirmIntent", "intentName": "MakeAppointment", "responseCard": { "genericAttachments": [ { "buttons": [ { "text": "yes", "value": "yes" }, { "text": "no", "value": "no" } ], "subTitle": "Is 4:00 p.m. on 2017-02-15 okay?", "title": "Confirm Appointment" } ], "version": 1, "contentType": "application/vnd.amazonaws.card.generic" } }, "sessionAttributes": { "bookingMap": "{\"2017-02-15\": [\"10:00\", \"16:00\", \"16:30\"]}" } }
同样,响应包含
dialogAction
和sessionAttributes
字段。此外,dialogAction
将返回以下字段:-
dialogAction
字段:-
type
—Lambda
函数将此值设置为ConfirmIntent
,从而指示 Amazon Lex 获取message
中建议的预约时间的用户确认。 -
responseCard
— 返回一个供用户选择的“是”或“否”值列表。如果客户端支持响应卡,则会显示响应卡,如下面的示例所示:
-
-
sessionAttributes
— Lambda 函数将设置bookingMap
会话属性,将其值设置为预约日期以及该日期的可用预约。在本示例中,这些是 30 分钟的预约。对于需要一个小时的牙根管手术,只能在下午 4 点预约。
-
-
如 Lambda 函数响应中的
dialogAction.type
所示,Amazon Lex 将向客户端返回以下响应:客户端会显示以下消息:2017 年 2 月 15 日的什么时间适合您?我们只有下午 4:00 有空,这个时间适合您吗?
-
-
用户:选择
yes
。Amazon Lex 将使用以下事件数据调用 Lambda 函数。由于用户回复了
yes
,Amazon Lex 将confirmationStatus
设置为Confirmed
,并将currentIntent.slots
中的Time
字段设置为4 p.m
。{ "currentIntent": { "slots": { "AppointmentType": "root canal", "Date": "2017-02-15", "Time": "16:00" }, "name": "MakeAppointment", "confirmationStatus": "Confirmed" }, "bot": { "alias": null, "version": "$LATEST", "name": "ScheduleAppointment" }, "userId": "u3fpr9gghj02zts7y5tpq5mm4din2xqy", "invocationSource": "FulfillmentCodeHook", "outputDialogMode": "Text", "messageVersion": "1.0", "sessionAttributes": { } }
由于
confirmationStatus
已获得确认,Lambda 函数将处理意图(预约牙医)并向 Amazon Lex 返回以下响应:{ "dialogAction": { "message": { "content": "Okay, I have booked your appointment. We will see you at 4:00 p.m. on 2017-02-15", "contentType": "PlainText" }, "type": "Close", "fulfillmentState": "Fulfilled" }, "sessionAttributes": { "formattedTime": "4:00 p.m.", "bookingMap": "{\"2017-02-15\": [\"10:00\"]}" } }
请注意以下几点:
-
Lambda 函数已更新
sessionAttributes
。 -
dialogAction.type
设置为Close
,这将指示 Amazon Lex 不要期待用户响应。 -
dialogAction.fulfillmentState
已设置为Fulfilled
,表示已成功完成目的。
客户端将显示消息:好的,我帮您预订好了。2017 年 2 月 15 日下午 4:00 见。
-