Flask сервер не получает запросы Alexa - PullRequest
0 голосов
/ 02 мая 2020

Справочная информация:

Я пытаюсь создать навык Alexa, который управляет визуализатором musi c через Raspberry Pi, но я борюсь с последним шагом на самом деле, чтобы Alexa взаимодействовала с Пи. Для сервера я использую Flask Ask. В большинстве уроков рекомендуется использовать ngrok или эквивалентный сервис для конечной точки Alexa, но ngrok генерирует случайные субдомены, и я не смог заставить работать ни одну из альтернатив, поэтому вместо этого я использую noip.com . У меня есть поддомен, который я буду называть subdomain.ddns.net, и я переадресую порт 443 (https) на порт 5000 на моем Raspberry Pi. Я установил http://subdomain.ddns.net в качестве конечной точки моего навыка Alexa и сгенерировал SSL-сертификат, используя инструкции Amazon .

Проблема:

Мой 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 -
  • Если я посещаю * 1020 вручную * с устройства, не входящего в мою локальную сеть (например, браузер моего телефона), я по-прежнему получаю вывод: <device IP> - - [02/May/2020 19:12:02] "GET / HTTP/1.1" 405 -
  • Если я остановлю сервер Flask и вместо этого запусту nc -l 5000, то отправлю команду моего навыка в Alexa я получаю некоторые (зашифрованные) данные, напечатанные со встроенной строкой subdomain.ddns.net, которая указывает, что запрос от Amazon успешно отправляется на мой Raspberry Pi через порт 5000.

Так что subdomain.ddns.net и переадресация портов, кажется, работают должным образом, и что-то из Amazon проходит, но сервер Flask не получает его. Я попытался добавить хук before_request в мое приложение Flask с помощью оператора print, но это никогда не срабатывает. Я впервые использую Flask, поэтому я не знаком ни с одной из его деталей. Есть ли, возможно, распространенная ошибка, в которую я впадаю? (Я уже установил host = "0.0.0.0" в качестве аргумента app.run(), я читал, что если вы этого не сделаете, вы ограничены только локальными соединениями.) Может кто-нибудь предложить подход к отладке этого?

Код сервера:

(я удалил части, которые указаны c для приложения визуализатора.)

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"))
...