Alexa Skill如何从S3拉取以detailNumber、pageNumber命名的图片
实现Alexa Skill从S3拉取指定图片的方案
前置配置
- 给技能对应的Lambda执行角色新增S3读取权限:配置IAM策略允许
s3:GetObject操作,资源路径填你的S3桶ARN,格式为arn:aws:s3:::你的桶名称/*(中国区AWS将aws改为aws-cn即可) - S3存储桶不需要全开公共权限,我们可以通过预签名URL生成临时可访问的HTTPS图片链接,Alexa设备仅支持公网可访问的HTTPS资源展示
- 到Alexa开发者控制台的当前技能配置页,开启APL(Alexa Presentation Language)渲染权限,允许技能输出屏幕内容
代码修改
你只需要调整OpenDetailIntentHandler的处理逻辑即可,修改后的完整代码如下:
import boto3 from botocore.exceptions import ClientError # 初始化S3客户端,替换为你的桶所在的区域 s3_client = boto3.client('s3', region_name='us-east-1') # 替换为你自己的S3桶名称 S3_BUCKET_NAME = '你的存储桶名称' class OpenDetailIntentHandler(AbstractRequestHandler): """Handler for Open Detail Intent.""" def can_handle(self, handler_input): # type: (HandlerInput) -> bool return ask_utils.is_intent_name("OpenDetailIntent")(handler_input) def handle(self, handler_input): # type: (HandlerInput) -> Response slots = handler_input.request_envelope.request.intent.slots detailNumber = slots["detailNumber"].value pageNumber = slots["pageNumber"].value # 构造目标文件名 image_file_name = f"{detailNumber}-{pageNumber}.png" try: # 先校验文件是否存在 s3_client.head_object(Bucket=S3_BUCKET_NAME, Key=image_file_name) # 生成有效期10分钟的预签名访问链接 image_url = s3_client.generate_presigned_url( 'get_object', Params={'Bucket': S3_BUCKET_NAME, 'Key': image_file_name}, ExpiresIn=600 ) speak_output = f'好的,已为你调出LSF {pageNumber} 页的 {detailNumber} 号详图。' # 构造APL简单图片展示模板 apl_document = { "type": "APL", "version": "1.7", "mainTemplate": { "parameters": ["payload"], "items": [ { "type": "Image", "source": image_url, "scale": "best-fit", "width": "100vw", "height": "100vh" } ] } } # 添加APL响应到返回结果 handler_input.response_builder.add_directive({ "type": "Alexa.Presentation.APL.RenderDocument", "document": apl_document, "datasources": {} }) except ClientError as e: if e.response['Error']['Code'] == '404': speak_output = f'抱歉,未找到LSF {pageNumber} 页的 {detailNumber} 号详图,请确认参数后重试。' else: speak_output = '当前服务暂时不可用,请稍后再试。' return ( handler_input.response_builder .speak(speak_output) .response )
补充说明
- 如果你已经将S3桶的图片目录设为公共可读,不需要预签名URL的话,直接将
image_url替换为公共访问路径即可,格式一般为https://{桶名}.s3.{区域}.amazonaws.com/{文件名} - 可以根据你的设备展示需求调整APL模板,增加标题、返回按钮等交互组件
内容的提问来源于stack exchange,提问作者James Hillegas
相关产品推荐
相关产品推荐

