Files

Piano di Sviluppo per la Lambda "Pompeo"

Questo documento descrive il piano di analisi, progettazione, implementazione e deploy per la funzione AWS Lambda che funge da ponte tra la skill Alexa "Pompeo" e l'istanza n8n del progetto ALPHA_PROJECT.

1. Obiettivo

La funzione Lambda ha un unico scopo: agire come un "ponte" (bridge) ultra-leggero e veloce. Il suo compito è ricevere le richieste inviate dalla skill Alexa, inoltrarle in modo sicuro al webhook di n8n che contiene la logica dell'agente, e restituire ad Alexa la risposta testuale (TTS) generata da n8n.


2. Analisi e Requisiti

Requisiti Funzionali

  1. Ricezione Richiesta: Deve essere in grado di ricevere e interpretare l'oggetto JSON inviato dal servizio Alexa.
  2. Inoltro a n8n: Deve inoltrare il corpo della richiesta Alexa a un webhook n8n predefinito.
  3. Autenticazione (Opzionale ma Raccomandato): La chiamata verso n8n dovrebbe includere un secret token per assicurare che solo la Lambda possa attivare il workflow.
  4. Ricezione Risposta da n8n: Deve attendere la risposta da n8n, che conterrà il testo da pronunciare.
  5. Formattazione Risposta Alexa: Deve costruire un oggetto JSON valido per Alexa, contenente la stringa TTS.
  6. Gestione Errori: Deve rispondere ad Alexa con un messaggio di errore cortese se n8n non è raggiungibile o restituisce un errore.

Requisiti Non Funzionali

  1. Costo Zero: L'intera infrastruttura deve operare sotto la soglia del piano gratuito di AWS (AWS Free Tier).
    • AWS Lambda: Il free tier include 1 milione di chiamate/mese e 400.000 GB-secondi, ampiamente sufficienti.
    • API Gateway (se usata): Il free tier include 1 milione di chiamate API/mese.
  2. Distribuzione Privata: La skill Alexa non deve essere pubblicata sullo store pubblico. Deve rimanere in stato "In Sviluppo" (development), rendendola automaticamente disponibile solo sui dispositivi Echo associati all'account Amazon dello sviluppatore.
  3. Bassa Latenza: La funzione deve essere scritta in un linguaggio performante per I/O (es. Python, Node.js) e avere una logica minimale per non introdurre ritardi.
  4. Sicurezza: La comunicazione tra Lambda e n8n deve avvenire su HTTPS. L'URL del webhook e il secret token devono essere gestiti tramite environment variables della Lambda, non hardcodati nel codice.

3. Progettazione (Design)

Architettura

+--------------+     1. Utente parla     +-----------------+     3. Inoltra richiesta     +---------------+
|              | ----------------------> |                 | --------------------------> |               |
|  Echo Device |                         |   AWS Lambda    |                             |  n8n Webhook  |
|              | <---------------------- |                 | <-------------------------  |               |
+--------------+    5. Risposta TTS      +-----------------+      4. Risposta TTS        +---------------+
                      (Text-to-Speech)
                               |
                               | 2. Trigger
                               |
                       +---------------------+
                       | Alexa Skills Kit    |
                       +---------------------+

Dettagli Tecnici

  • Runtime: Python 3.11. È una scelta eccellente per task I/O-bound come questo, con un'ottima integrazione in ambiente AWS.
  • Trigger: Il trigger della Lambda sarà "Alexa Skills Kit". Per sicurezza, verrà configurato per accettare chiamate solo dalla specifica Skill ID di "Pompeo".
  • IAM Role: Verrà creato un ruolo IAM con due policy:
    1. Trust Policy: Permette al servizio lambda.amazonaws.com di assumere questo ruolo.
    2. Permissions Policy: Si utilizzerà la policy gestita da AWS AWSLambdaBasicExecutionRole, che garantisce i permessi necessari per scrivere log su Amazon CloudWatch (logs:CreateLogGroup, logs:CreateLogStream, logs:PutLogEvents). Non sono necessari altri permessi.
  • Logica del Codice (Python):
    1. La funzione lambda_handler(event, context) sarà il punto di ingresso.
    2. Recupererà l'URL del webhook e il secret token dalle variabili d'ambiente (os.environ.get('N8N_WEBHOOK_URL')).
    3. Eseguirà una richiesta HTTP POST (usando la libreria requests o urllib3) verso l'URL di n8n.
    4. Il body della POST conterrà l'intero oggetto event ricevuto da Alexa. L'header conterrà il secret token.
    5. Attenderà la risposta di n8n. Se la risposta è 200 OK e contiene un JSON con un campo tts_response, procederà.
    6. Costruirà l'oggetto di risposta per Alexa, come da documentazione ufficiale.
  • Gestione degli Errori: In caso di timeout, codice di stato HTTP non-200, o JSON malformato da n8n, la Lambda costruirà una risposta di errore standard per Alexa (es. "Mi dispiace, si è verificato un problema. Riprova più tardi.").

4. Implementazione (Codice)

La Lambda richiederà un singolo file index.py e un file requirements.txt per le dipendenze.

requirements.txt:

requests

index.py (Esempio Boilerplate):

import os
import json
import requests

# Recupera le variabili d'ambiente
N8N_WEBHOOK_URL = os.environ.get('N8N_WEBHOOK_URL')
N8N_SECRET_TOKEN = os.environ.get('N8N_SECRET_TOKEN')

def build_alexa_response(text):
    """Costruisce la risposta JSON per Alexa."""
    return {
        'version': '1.0',
        'response': {
            'outputSpeech': {
                'type': 'PlainText',
                'text': text
            },
            'shouldEndSession': True
        }
    }

def lambda_handler(event, context):
    """Punto di ingresso della funzione Lambda."""
    print(f"Richiesta ricevuta da Alexa: {json.dumps(event)}")

    if not N8N_WEBHOOK_URL or not N8N_SECRET_TOKEN:
        print("Errore: Variabili d'ambiente non configurate.")
        return build_alexa_response("Errore di configurazione del server.")

    headers = {
        'Content-Type': 'application/json',
        'X-N8N-Webhook-Secret': N8N_SECRET_TOKEN
    }

    try:
        response = requests.post(
            N8N_WEBHOOK_URL,
            headers=headers,
            data=json.dumps(event),
            timeout=8  # Alexa attende max 10 secondi
        )
        response.raise_for_status()  # Solleva un'eccezione per status code non-2xx

        n8n_data = response.json()
        tts_text = n8n_data.get('tts_response', 'Nessuna risposta ricevuta da Pompeo.')

        print(f"Risposta da n8n: {tts_text}")
        return build_alexa_response(tts_text)

    except requests.exceptions.RequestException as e:
        print(f"Errore nella chiamata a n8n: {e}")
        return build_alexa_response("Mi dispiace, non riesco a contattare Pompeo in questo momento.")
    except Exception as e:
        print(f"Errore generico: {e}")
        return build_alexa_response("Si è verificato un errore inaspettato.")

Il codice andrà zippato insieme alla cartella delle dipendenze installate localmente (pip install -r requirements.txt -t .).


5. Procedura Burocratica di Deploy e Configurazione

Questa è la checklist passo-passo per mettere tutto in funzione.

Passo 1: Creazione del Ruolo IAM

  1. Vai alla console AWS -> IAM -> Roles.
  2. Clicca su Create role.
  3. Trusted entity type: Seleziona AWS service.
  4. Use case: Seleziona Lambda, poi clicca Next.
  5. Nella pagina Add permissions, cerca e seleziona la policy AWSLambdaBasicExecutionRole. Clicca Next.
  6. Role name: Inserisci un nome, es. PompeoAlexaLambdaRole.
  7. Clicca Create role.

Passo 2: Creazione della Funzione Lambda

  1. Prepara il pacchetto di deploy:
    • Crea una cartella, es. lambda_package.
    • Salva il codice Python come index.py in quella cartella.
    • Salva requirements.txt.
    • Da terminale, nella cartella, esegui: pip install -r requirements.txt --target .
    • Zippa l'intero contenuto della cartella lambda_package (non la cartella stessa).
  2. Vai alla console AWS -> Lambda.
  3. Clicca Create function.
  4. Seleziona Author from scratch.
  5. Function name: pompeo-alexa-bridge.
  6. Runtime: Seleziona Python 3.11.
  7. Architecture: x86_64.
  8. Permissions: Espandi "Change default execution role", seleziona "Use an existing role" e scegli il ruolo PompeoAlexaLambdaRole creato prima.
  9. Clicca Create function.
  10. Nella pagina della funzione, vai su Code source e clicca Upload from -> .zip file. Carica lo zip creato.
  11. Vai in Configuration -> Environment variables e aggiungi:
    • N8N_WEBHOOK_URL: L'URL del tuo webhook n8n.
    • N8N_SECRET_TOKEN: Il token segreto che configurerai su n8n.

Passo 3: Creazione della Skill Alexa "Pompeo"

  1. Vai su Alexa Developer Console.
  2. Clicca Create Skill.
  3. Skill name: Pompeo.
  4. Choose a model: Custom.
  5. Choose a method to host: Provision your own.
  6. Clicca Create skill.
  7. Una volta nella dashboard della skill, vai nel menu a sinistra su Endpoint.
  8. Copia il tuo Skill ID. Sarà una stringa simile a amzn1.ask.skill.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.

Passo 4: Collegamento tra Skill e Lambda

  1. Torna alla pagina della funzione Lambda su AWS.
  2. Nella sezione Function overview, clicca Add trigger.
  3. Come sorgente, seleziona Alexa Skills Kit.
  4. Abilita Skill ID verification e incolla lo Skill ID copiato dal portale Alexa.
  5. Clicca Add.
  6. Ora, nella pagina della Lambda, in alto a destra, copia l'ARN (Amazon Resource Name) della funzione.
  7. Torna alla pagina Endpoint della skill nella Alexa Developer Console.
  8. Seleziona AWS Lambda ARN come Service Endpoint Type.
  9. Incolla l'ARN della Lambda nel campo Default Region.
  10. Clicca Save Endpoints in alto.

Passo 5: Test

  1. Nella Alexa Developer Console, vai alla tab Test.
  2. Nella casella di testo, scrivi "apri pompeo" o qualsiasi altra frase di avvio.
  3. Controlla i log della funzione Lambda su AWS CloudWatch per vedere la richiesta in arrivo e la risposta.
  4. La skill è ora attiva in modalità "Development" e funzionerà su tutti i dispositivi Echo associati al tuo account Amazon, rimanendo completamente privata.