【问题标题】:Alexa Skill To Download File From Google DriveAlexa 从 Google Drive 下载文件的技能
【发布时间】:2018-05-13 04:44:12
【问题描述】:

我正在尝试使用我用树莓派 3 制作的 Alexa Skill 和 Amazon Echo 从谷歌驱动器下载文件。我的 lambda 函数如下:-

#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import print_function
import xml.etree.ElementTree as etree
from datetime import datetime as dt
import os
import urllib
import requests

from urllib.parse import urlparse


def lambda_handler(event, context):
    """ Route the incoming request based on type (LaunchRequest, IntentRequest,
    etc.) The JSON body of the request is provided in the event parameter.
    """

    print('event.session.application.applicationId=' + event['session'
          ]['application']['applicationId'])

    # if (event['session']['application']['applicationId'] !=
    #         "amzn1.echo-sdk-ams.app.[unique-value-here]"):
    #     raise ValueError("Invalid Application ID")

    if event['session']['new']:
        on_session_started({'requestId': event['request']['requestId'
                           ]}, event['session'])

    if event['request']['type'] == 'LaunchRequest':
        return on_launch(event['request'], event['session'])
    elif event['request']['type'] == 'IntentRequest':
        return on_intent(event['request'], event['session'])
    elif event['request']['type'] == 'SessionEndedRequest':
        return on_session_ended(event['request'], event['session'])


def on_session_started(session_started_request, session):
    """ Called when the session starts """

    print('on_session_started requestId='
          + session_started_request['requestId'] + ', sessionId='
          + session['sessionId'])


def on_launch(launch_request, session):
    """ Called when the user launches the skill without specifying what they
    want
    """

    print('on_launch requestId=' + launch_request['requestId']
          + ', sessionId=' + session['sessionId'])

    # Dispatch to your skill's launch

    return get_welcome_response()


def on_intent(intent_request, session):
    """ Called when the user specifies an intent for this skill """

    print('on_intent requestId=' + intent_request['requestId']
          + ', sessionId=' + session['sessionId'])

    intent = intent_request['intent']
    intent_name = intent_request['intent']['name']

    # Dispatch to your skill's intent handlers

    if intent_name == 'DownloadFiles':
        return get_file(intent, session)
    elif intent_name == 'AMAZON.HelpIntent':
        return get_welcome_response()
    else:
        raise ValueError('Invalid intent')


def on_session_ended(session_ended_request, session):
    """ Called when the user ends the session.Is not called when the skill returns should_end_session=true """

    print('on_session_ended requestId='
          + session_ended_request['requestId'] + ', sessionId='
          + session['sessionId'])


    # add cleanup logic here

# --------------- Functions that control the skill's behavior ------------------

def get_welcome_response():
    """ If we wanted to initialize the session to have some attributes we could add those here """

    session_attributes = {}
    card_title = 'Welcome'
    speech_output = \
        "Welcome to file download Application. Please ask me to download files by saying, Ask auto downloader for download"

    # If the user either does not reply to the welcome message or says something
    # that is not understood, they will be prompted again with this text.

    reprompt_text = \
        "Please ask me to download files by saying, Ask auto downloader for download"
    should_end_session = False
    return build_response(session_attributes,
                          build_speechlet_response(card_title,
                          speech_output, reprompt_text,
                          should_end_session))


def get_file(intent, session):
    """ Grabs the files from the path that have to be downloaded """

    card_title = intent['name']
    session_attributes = {}
    should_end_session = True
    username = '*******'
    password = '*******'

    url = 'https://drive.google.com/drive/my-drive/abc.pdf'
    filename = os.path.basename(urlparse(url).path)

    # urllib.urlretrieve(url, "code.zip")

    r = requests.get(url, auth=(username, password))

    if r.status_code == 200:
        with open(filename, 'wb') as out:
            for bits in r.iter_content():
                out.write(bits)

    speech_output = 'The file filename has been downloaded'
    return build_response(session_attributes,
                          build_speechlet_response(card_title,
                          speech_output, reprompt_text,
                          should_end_session))


# --------------- Helpers that build all of the responses ----------------------

def build_speechlet_response(
    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 build_response(session_attributes, speechlet_response):
    return {'version': '1.0', 'sessionAttributes': session_attributes,
            'response': speechlet_response}

运行此 lambda_function 后,我收到以下错误:-

[Errno 30] Read-only file system: 'abc.pdf': OSError
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 32, in lambda_handler
return on_intent(event['request'], event['session'])
File "/var/task/lambda_function.py", line 70, in on_intent
return get_file(intent, session)
File "/var/task/lambda_function.py", line 126, in get_file
with open(filename, 'wb') as out:
OSError: [Errno 30] Read-only file system: 'abc.pdf'

谁能建议如何解决这个错误!我想要的是 Alexa 会被提示使用 amazon echo 从固定 url 下载文件。

【问题讨论】:

    标签: python amazon-web-services aws-lambda alexa-skills-kit


    【解决方案1】:

    确保写入 /tmp,因为它是 lambda 中唯一可写的路径。

    with open("/tmp/" + filename, 'wb') as out:
                for bits in r.iter_content():
                    out.write(bits)
    

    【讨论】:

    • 嗨潘德利斯。谢谢!它解决了错误。该文件被下载到 /tmp 目录中,对吗?如何访问 /tmp 目录中的文件?有没有办法可以将文件下载到我的本地系统文件夹中?
    • 不,lambda 在云中运行,而不是在您的计算机上
    • 好的。那么如何从 /tmp 目录访问文件呢?抱歉,我是 AWS 和 Lambda 的新手。
    • 您必须将其上传到您可以访问的地方。 S3 也许?
    • 我如何下载文件并在相同的代码中将其上传到 S3?你能帮忙@pandelis 吗?
    猜你喜欢
    • 1970-01-01
    • 2022-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多