Flask服务器未收到Alexa请求

时间:2020-05-02 18:46:01

标签: amazon-web-services flask raspberry-pi alexa noip

背景:

我正在尝试建立一种通过Raspberry Pi控制音乐可视化程序的Alexa技能,但是我为使Alexa与Pi进行通信的最后一步而苦苦挣扎。对于服务器,我正在使用Flask Ask。大多数教程建议为Alexa终结点使用ngrok或等效服务,但是ngrok会生成随机子域,并且我无法使用任何替代方法,因此我使用noip.com。我有一个子域,我将其称为subdomain.ddns.net,并且将端口443(https)转发到Raspberry Pi上的端口5000。我已经将http://subdomain.ddns.net设置为我的Alexa技能的端点,并且已经使用Amazon's instructions生成了SSL证书。

问题:

我的Flask服务器(但不是我的本地网络或Raspberry Pi)似乎正在忽略或未接收到来自Alexa服务器的请求。当我尝试触发自己的技能意图时,Alexa会给我响应“我无法达到所要求的技能”,并且Flask服务器控制台不会产生任何输出。但是:

  • 如果我从本地网络上的设备手动访问https://subdomain.ddns.net/,则Flask会向控制台生成输出:192.168.1.1 - - [02/May/2020 19:10:48] "GET / HTTP/1.1" 405 -
  • 如果我从不在本地网络上的设备(例如手机的浏览器)手动访问https://subdomain.ddns.net/,我仍然会收到输出:<device IP> - - [02/May/2020 19:12:02] "GET / HTTP/1.1" 405 -
  • 如果我停止了Flask服务器,而是运行nc -l 5000,然后将我的技能命令发送给Alexa,我得到了一些(加密的)打印有嵌入字符串subdomain.ddns.net的数据,这表明来自Amazon 的请求已成功发送到端口5000上的Raspberry Pi。

因此subdomain.ddns.net和端口转发似乎正常运行,并且来自Amazon的某些消息正在通过,但是Flask服务器没有接好它。我尝试使用打印语句将before_request挂钩添加到我的Flask应用程序中,但从未触发。这是我第一次使用Flask,所以我对它的任何细节都不熟悉。我可能会遇到一个常见的陷阱吗? (我已经将host = "0.0.0.0"设置为app.run()的参数,我读过,如果不这样做,则只能使用本地主机连接。)任何人都可以建议一种调试方法这个吗?

服务器代码:

(我已经删除了可视化应用程序专用的部分。)

from flask import Flask
from flask_ask import Ask, request, session, question, statement
import numpy
import soco
import sounddevice
import os
import subprocess
import threading
import time
import wave

...

app = Flask(__name__)
ask = Ask(app, "/")

@ask.launch
def launch():
    print("Received launch intent")
    speech_text = "Visualizer server online."
    return question(speech_text).reprompt(speech_text).simple_card(speech_text)

@ask.intent("start")
def start_intent(status, room):
    print("Received start intent")
    ...
    return statement("Starting the visualizer.")

@ask.intent("stop")
def stop_intent(status, room):
    print("Received stop intent")
    ...
    return statement("Stopping the visualizer.")

@ask.intent("restart")
def restart_intent(status, room):
    print("Received restart intent")

    def run():
        time.sleep(3)
        os.system("reboot now")
    threading.Thread(target = run)
    return statement("Restarting the visualizer server.")

@ask.intent("AMAZON.HelpIntent")
def help_intent():
    print("Received help intent")

    speech_text = "Commands are start, stop, and restart."
    return question(speech_text).reprompt(speech_text).simple_card("HelloWorld", speech_text)

@ask.session_ended
def session_ended():
    return ("{}", 200)

...

if __name__ == "__main__":
    if "ASK_VERIFY_REQUESTS" in os.environ:
        verify = str(os.environ.get("ASK_VERIFY_REQUESTS", "")).lower()
        if verify == "false":
            app.config["ASK_VERIFY_REQUESTS"] = False
    app.run(host = "0.0.0.0", ssl_context = ("certificate.pem", "private-key.pem"))

0 个答案:

没有答案