# 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):** ```python 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](https://developer.amazon.com/alexa/console/ask). 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.