Amazon Lex响应卡片网站不显示问题及按钮替代方案咨询
替代响应卡片的按钮实现方案
首先,你的Lambda代码在Lex控制台能正常触发响应卡片,说明逻辑没问题,问题大概率出在网站端的Lex集成客户端没有正确解析responseCard格式。下面给你几个不依赖原生响应卡片的替代方案,都能在网站上显示交互按钮:
1. 前端手动解析Lex返回的按钮数据
Lambda返回的responseCard里的按钮信息其实已经包含在返回结果中了,你可以让前端直接提取这些数据,手动渲染HTML按钮。
比如你的Lambda返回结果里,按钮数据在responseCard.genericAttachments[0].buttons这个路径下。前端拿到Lex的响应后,就可以循环这个数组,创建对应的按钮,点击按钮时把按钮的value作为用户输入发送给Lex。
举个前端伪代码示例(假设用JavaScript):
// 假设lexResponse是从Lex拿到的完整响应 const buttons = lexResponse.dialogAction.responseCard.genericAttachments[0].buttons; const buttonContainer = document.getElementById('button-container'); buttons.forEach(btn => { const button = document.createElement('button'); button.textContent = btn.text; button.addEventListener('click', () => { // 把btn.value作为用户输入发送给Lex sendToLex(btn.value); }); buttonContainer.appendChild(button); });
2. 用会话上下文(Session Attributes)传递按钮信息
你可以在Lambda里把按钮的text和value存入sessionAttributes,前端读取这些属性后再渲染按钮,这种方式不依赖Lex的响应卡片解析逻辑,兼容性更好。
修改你的Lambda代码里的close函数:
import json import logging logger = logging.getLogger() logger.setLevel(logging.DEBUG) def close(): # 定义按钮数据 buttons = [ {"text":"button 1", "value":"value 1"}, {"text":"button 2", "value":"value 2"}, {"text":"button 3", "value":"value 3"} ] val= { "dialogAction": { "fulfillmentState":"Fulfilled", "type":"Close", "message": { "contentType":"PlainText", "content":"Hey your ticket has been raised" } }, # 把按钮数据存入会话属性(转成JSON字符串) "sessionAttributes": { "actionButtons": json.dumps(buttons) } } print(val) return val # 其他函数保持不变 def lambda_handler(event, context): slots = event['currentIntent']['slots'] empidemployee= event['currentIntent']["slots"]["empidemployee"] latestdesc= event['currentIntent']["slots"]["latestdesc"] latestservice= event['currentIntent']["slots"]["latestservice"] latestimpactvalue= event['currentIntent']["slots"]["latestimpactvalue"] latesturgency= event['currentIntent']["slots"]["latesturgency"] basicinfo=event['currentIntent']["slots"]["basicinfo"] val=close() return val
前端拿到响应后,解析sessionAttributes.actionButtons,然后按照第一种方案的逻辑渲染按钮即可。
3. 自定义JSON格式消息,前端解析渲染
把Lex消息的contentType改成application/json,在content里同时包含文本和按钮信息,前端识别这个类型后解析并渲染。
修改Lambda的close函数:
import json import logging logger = logging.getLogger() logger.setLevel(logging.DEBUG) def close(): val= { "dialogAction": { "fulfillmentState":"Fulfilled", "type":"Close", "message": { "contentType":"application/json", "content": json.dumps({ "text": "Hey your ticket has been raised", "buttons": [ {"text":"button 1", "value":"value 1"}, {"text":"button 2", "value":"value 2"}, {"text":"button 3", "value":"value 3"} ] }) } } } print(val) return val # 其他函数保持不变 def lambda_handler(event, context): slots = event['currentIntent']['slots'] empidemployee= event['currentIntent']["slots"]["empidemployee"] latestdesc= event['currentIntent']["slots"]["latestdesc"] latestservice= event['currentIntent']["slots"]["latestservice"] latestimpactvalue= event['currentIntent']["slots"]["latestimpactvalue"] latesturgency= event['currentIntent']["slots"]["latesturgency"] basicinfo=event['currentIntent']["slots"]["basicinfo"] val=close() return val
前端处理时,判断消息的contentType是application/json,就解析content字段,显示文本并渲染按钮:
if (lexResponse.dialogAction.message.contentType === 'application/json') { const messageData = JSON.parse(lexResponse.dialogAction.message.content); // 显示文本 document.getElementById('chat-message').textContent = messageData.text; // 渲染按钮 const buttonContainer = document.getElementById('button-container'); messageData.buttons.forEach(btn => { const button = document.createElement('button'); button.textContent = btn.text; button.addEventListener('click', () => sendToLex(btn.value)); buttonContainer.appendChild(button); }); }
这些方案都绕开了Lex原生响应卡片的解析限制,完全由前端控制按钮的渲染,兼容性和灵活性都更强。
内容的提问来源于stack exchange,提问作者lakshmi

