Files
Alpha/aws-lambda/README.md

207 lines
10 KiB
Markdown

# 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.