

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Tutorial: creazione di un endpoint webhook utilizzando l'URL di una funzione Lambda
<a name="urls-webhook-tutorial"></a>

In questo tutorial, crei l'URL di una funzione Lambda per implementare un endpoint webhook. Un webhook è una comunicazione leggera basata sugli eventi che invia automaticamente i dati tra le applicazioni tramite HTTP. È possibile utilizzare un webhook per ricevere aggiornamenti immediati sugli eventi che si verificano in un altro sistema, ad esempio quando un nuovo cliente si registra su un sito Web, viene elaborato un pagamento o viene caricato un file.

Con Lambda, i webhook possono essere implementati utilizzando la funzione Lambda o l'API Gateway. URLs URLs Le funzioni sono un'ottima scelta per webhook semplici che non richiedono funzionalità come l'autorizzazione avanzata o la convalida delle richieste.

**Suggerimento**  
Se non sei sicuro di quale sia la soluzione migliore per il tuo caso d'uso particolare, consulta. [Selezionare un metodo per richiamare la funzione Lambda tramite una richiesta HTTP](furls-http-invoke-decision.md)

## Prerequisiti
<a name="urls-webhook-tutorial-prereqs"></a>

Per completare questo tutorial, devi avere Python (versione 3.8 o successiva) o Node.js (versione 18 o successiva) installato sul tuo computer locale.

Per testare l'endpoint utilizzando una richiesta HTTP, il tutorial utilizza [curl](https://curl.se/), uno strumento a riga di comando che è possibile utilizzare per trasferire dati utilizzando vari protocolli di rete. Fai riferimento alla [documentazione di curl](https://curl.se/docs/install.html) per scoprire come installare lo strumento se non lo possiedi già.

## Creazione della funzione Lambda
<a name="urls-webhook-tutorial-function"></a>

Per prima cosa crea la funzione Lambda che viene eseguita quando una richiesta HTTP viene inviata al tuo endpoint webhook. In questo esempio, l'applicazione di invio invia un aggiornamento ogni volta che viene inviato un pagamento e indica nel corpo della richiesta HTTP se il pagamento è andato a buon fine. La funzione Lambda analizza la richiesta e interviene in base allo stato del pagamento. In questo esempio, il codice stampa solo l'ID dell'ordine per il pagamento, ma in un'applicazione reale è possibile aggiungere l'ordine a un database o inviare una notifica.

La funzione implementa anche il metodo di autenticazione più comune utilizzato per i webhook, l'autenticazione dei messaggi basata su hash (HMAC). Con questo metodo, sia l'applicazione di invio che quella di ricezione condividono una chiave segreta. L'applicazione di invio utilizza un algoritmo di hashing per generare una firma univoca utilizzando questa chiave insieme al contenuto del messaggio e include la firma nella richiesta del webhook come intestazione HTTP. L'applicazione ricevente ripete quindi questo passaggio, generando la firma utilizzando la chiave segreta e confronta il valore risultante con la firma inviata nell'intestazione della richiesta. Se il risultato corrisponde, la richiesta viene considerata legittima. 

Crea la funzione utilizzando la console Lambda con il runtime Python o Node.js.

------
#### [ Python ]

**Creazione della funzione Lambda**

1. Aprire la pagina [Funzioni](https://console.aws.amazon.com/lambda/home#/functions) della console Lambda.

1. Crea una funzione di base «Hello world» effettuando le seguenti operazioni:

   1. Scegli **Crea funzione**.

   1. Scegli **Crea da zero**.

   1. Nel campo **Function name (Nome funzione)**, immettere **myLambdaWebhook**.

   1. **Per **Runtime**, seleziona python3.14.**

   1. Scegli **Crea funzione**.

1. Nel riquadro **Codice sorgente**, sostituisci il codice esistente copiando e incollando quanto segue:

   ```
   import json
   import hmac
   import hashlib
   import os
   
   def lambda_handler(event, context):
       
       # Get the webhook secret from environment variables
       webhook_secret = os.environ['WEBHOOK_SECRET']
       
       # Verify the webhook signature
       if not verify_signature(event, webhook_secret):
           return {
               'statusCode': 401,
               'body': json.dumps({'error': 'Invalid signature'})
           }
       
       try:
           # Parse the webhook payload
           payload = json.loads(event['body'])
           
           # Handle different event types
           event_type = payload.get('type')
           
           if event_type == 'payment.success':
               # Handle successful payment
               order_id = payload.get('orderId')
               print(f"Processing successful payment for order {order_id}")
               
               # Add your business logic here
               # For example, update database, send notifications, etc.
               
           elif event_type == 'payment.failed':
               # Handle failed payment
               order_id = payload.get('orderId')
               print(f"Processing failed payment for order {order_id}")
               
               # Add your business logic here
               
           else:
               print(f"Received unhandled event type: {event_type}")
           
           # Return success response
           return {
               'statusCode': 200,
               'body': json.dumps({'received': True})
           }
           
       except json.JSONDecodeError:
           return {
               'statusCode': 400,
               'body': json.dumps({'error': 'Invalid JSON payload'})
           }
       except Exception as e:
           print(f"Error processing webhook: {e}")
           return {
               'statusCode': 500,
               'body': json.dumps({'error': 'Internal server error'})
           }
   
   def verify_signature(event, webhook_secret):
       """
       Verify the webhook signature using HMAC
       """
       try:
           # Get the signature from headers
           signature = event['headers'].get('x-webhook-signature')
   
           if not signature:
               print("Error: Missing webhook signature in headers")
               return False
           
           # Get the raw body (return an empty string if the body key doesn't exist)
           body = event.get('body', '')
           
           # Create HMAC using the secret key
           expected_signature = hmac.new(
               webhook_secret.encode('utf-8'),
               body.encode('utf-8'),
               hashlib.sha256
           ).hexdigest()
           
           # Compare the expected signature with the received signature to authenticate the message
           is_valid = hmac.compare_digest(signature, expected_signature)
           if not is_valid:
               print(f"Error: Invalid signature. Received: {signature}, Expected: {expected_signature}")
               return False
               
           return True
       except Exception as e:
           print(f"Error verifying signature: {e}")
           return False
   ```

1. Nella sezione **DEPLOY**, scegli **Implementa** per aggiornare il codice della tua funzione.

------
#### [ Node.js ]

**Creazione della funzione Lambda**

1. Aprire la pagina [Funzioni](https://console.aws.amazon.com/lambda/home#/functions) della console Lambda.

1. Crea una funzione di base «Hello world» effettuando le seguenti operazioni:

   1. Scegli **Crea funzione**.

   1. Scegli **Crea da zero**.

   1. Nel campo **Function name (Nome funzione)**, immettere **myLambdaWebhook**.

   1. **Per **Runtime**, seleziona nodejs24.x.**

   1. Scegli **Crea funzione**.

1. Nel riquadro **Codice sorgente**, sostituisci il codice esistente copiando e incollando quanto segue:

   ```
   import crypto from 'crypto';
   
   export const handler = async (event, context) => {
       // Get the webhook secret from environment variables
       const webhookSecret = process.env.WEBHOOK_SECRET;
   
       // Verify the webhook signature
       if (!verifySignature(event, webhookSecret)) {
           return {
               statusCode: 401,
               body: JSON.stringify({ error: 'Invalid signature' })
           };
       }
   
       try {
           // Parse the webhook payload
           const payload = JSON.parse(event.body);
   
           // Handle different event types
           const eventType = payload.type;
   
           switch (eventType) {
               case 'payment.success': {
                   // Handle successful payment
                   const orderId = payload.orderId;
                   console.log(`Processing successful payment for order ${orderId}`);
   
                   // Add your business logic here
                   // For example, update database, send notifications, etc.
                   break;
               }
   
               case 'payment.failed': {
                   // Handle failed payment
                   const orderId = payload.orderId;
                   console.log(`Processing failed payment for order ${orderId}`);
   
                   // Add your business logic here
                   break;
               }
   
               default:
                   console.log(`Received unhandled event type: ${eventType}`);
           }
   
           // Return success response
           return {
               statusCode: 200,
               body: JSON.stringify({ received: true })
           };
   
       } catch (error) {
           if (error instanceof SyntaxError) {
               // Handle JSON parsing errors
               return {
                   statusCode: 400,
                   body: JSON.stringify({ error: 'Invalid JSON payload' })
               };
           }
   
           // Handle all other errors
           console.error('Error processing webhook:', error);
           return {
               statusCode: 500,
               body: JSON.stringify({ error: 'Internal server error' })
           };
       }
   };
   
   // Verify the webhook signature using HMAC
   
   const verifySignature = (event, webhookSecret) => {
       try {
           // Get the signature from headers
           const signature = event.headers['x-webhook-signature'];
     
           if (!signature) {
               console.log('No signature found in headers:', event.headers);
               return false;
           }
     
           // Get the raw body (return an empty string if the body key doesn't exist)
           const body = event.body || '';
     
           // Create HMAC using the secret key
           const hmac = crypto.createHmac('sha256', webhookSecret);
           const expectedSignature = hmac.update(body).digest('hex');
     
           // Compare expected and received signatures
           const isValid = signature === expectedSignature;
           if (!isValid) {
               console.log(`Invalid signature. Received: ${signature}, Expected: ${expectedSignature}`);
               return false;
           }
           
           return true;
       } catch (error) {
           console.error('Error during signature verification:', error);
           return false;
       }
     };
   ```

1. Nella sezione **DEPLOY**, scegli **Implementa** per aggiornare il codice della tua funzione.

------

## Crea la chiave segreta
<a name="urls-webhook-tutorial-key"></a>

Per autenticare la richiesta webhook, la funzione Lambda utilizza una chiave segreta che condivide con l'applicazione chiamante. In questo esempio, la chiave viene memorizzata in una variabile di ambiente. In un'applicazione di produzione, non includere informazioni sensibili come le password nel codice funzione. Invece, [crea un Gestione dei segreti AWS segreto](https://docs.aws.amazon.com/secretsmanager/latest/userguide/create_secret.html) e poi [usa l'estensione Lambda AWS Parameters and Secrets](with-secrets-manager.md) per recuperare le credenziali nella funzione Lambda.

**Crea e archivia la chiave segreta del webhook**

1. Genera una stringa lunga e casuale utilizzando un generatore di numeri casuali crittograficamente sicuro. Puoi usare i seguenti frammenti di codice in Python o Node.js per generare e stampare un segreto di 32 caratteri o usare il tuo metodo preferito.

------
#### [ Python ]

**Example codice per generare un segreto**  

   ```
   import secrets
   webhook_secret = secrets.token_urlsafe(32)
   print(webhook_secret)
   ```

------
#### [ Node.js ]

**Example codice per generare un segreto (formato del modulo ES)**  

   ```
   import crypto from 'crypto';
   let webhookSecret = crypto.randomBytes(32).toString('base64');
   console.log(webhookSecret)
   ```

------

1. Memorizza la stringa generata come variabile di ambiente per la tua funzione effettuando le seguenti operazioni:

   1. Nella scheda **Configurazione** della funzione, seleziona **Variabili di ambiente**.

   1. Scegli **Modifica**.

   1. Scegli **Add environment variable (Aggiungi variabile d'ambiente)**.

   1. Per **Chiave****WEBHOOK\$1SECRET**, inserisci, quindi per **Valore**, inserisci il segreto generato nel passaggio precedente.

   1. Scegli **Save** (Salva).

Dovrai utilizzare nuovamente questo segreto più avanti nel tutorial per testare la tua funzione, quindi prendine nota ora.

## Crea l'endpoint URL della funzione
<a name="urls-webhook-tutorial-furl"></a>

Crea un endpoint per il tuo webhook utilizzando l'URL di una funzione Lambda. Poiché utilizzi il tipo di autenticazione di `NONE` per creare un endpoint con accesso pubblico, chiunque disponga dell'URL può richiamare la tua funzione. Per ulteriori informazioni sul controllo dell'accesso alla funzione, consulta. URLs [Controlla l'accesso alla funzione Lambda URLs](urls-auth.md) Se hai bisogno di opzioni di autenticazione più avanzate per il tuo webhook, prendi in considerazione l'utilizzo di API Gateway.

**Crea l'endpoint URL della funzione**

1. Nella scheda **Configurazione** della funzione, selezionate **Function URL**.

1. Scegli **Crea URL della funzione**.

1. Per il **tipo di autenticazione**, seleziona **NESSUNA**.

1. Scegli **Save** (Salva).

L'endpoint per l'URL della funzione appena creato viene visualizzato nel riquadro **URL della funzione**. Copia l'endpoint per utilizzarlo più avanti nel tutorial.

## Prova la funzione nella console
<a name="urls-webhook-tutorial-test-console"></a>

Prima di utilizzare una richiesta HTTP per richiamare la funzione utilizzando l'endpoint URL, testala nella console per confermare che il codice funzioni come previsto.

Per verificare la funzione nella console, devi prima calcolare una firma webhook utilizzando il segreto generato in precedenza nel tutorial con il seguente payload JSON di test:

```
{
    "type": "payment.success", 
    "orderId": "1234",
    "amount": "99.99"
}
```

Usa uno dei seguenti esempi di codice Python o Node.js per calcolare la firma del webhook usando il tuo segreto.

------
#### [ Python ]

**Calcola la firma del webhook**

1. Salva il codice seguente come file denominato`calculate_signature.py`. Sostituisci il webhook secret nel codice con il tuo valore.

   ```
   import secrets
   import hmac
   import json
   import hashlib
   
   webhook_secret = "arlbSDCP86n_1H90s0fL_Qb2NAHBIBQOyGI0X4Zay4M"
   
   body = json.dumps({"type": "payment.success", "orderId": "1234", "amount": "99.99"})
   
   signature = hmac.new(
               webhook_secret.encode('utf-8'),
               body.encode('utf-8'),
               hashlib.sha256
           ).hexdigest()
   
   print(signature)
   ```

1. Calcola la firma eseguendo il comando seguente dalla stessa directory in cui hai salvato il codice. Copia la firma generata dal codice.

   ```
   python calculate_signature.py
   ```

------
#### [ Node.js ]

**Calcola la firma del webhook**

1. Salva il codice seguente come file denominato`calculate_signature.mjs`. Sostituisci il webhook secret nel codice con il tuo valore.

   ```
   import crypto from 'crypto';
   
   const webhookSecret = "arlbSDCP86n_1H90s0fL_Qb2NAHBIBQOyGI0X4Zay4M"
   const body = "{\"type\": \"payment.success\", \"orderId\": \"1234\", \"amount\": \"99.99\"}";
   
   let hmac = crypto.createHmac('sha256', webhookSecret);
   let signature = hmac.update(body).digest('hex');
   
   console.log(signature);
   ```

1. Calcola la firma eseguendo il comando seguente dalla stessa directory in cui hai salvato il codice. Copia la firma generata dal codice.

   ```
   node calculate_signature.mjs
   ```

------

Ora puoi testare il codice della funzione utilizzando una richiesta HTTP di prova nella console.

**Prova la funzione nella console**

1. Seleziona la scheda **Codice** relativa alla tua funzione.

1. Nella sezione **EVENTI DI TEST**, scegli **Crea nuovo evento di test**

1. Per **Event name** (Nome evento), immettere **myEvent**.

1. Sostituisci il JSON esistente copiando e incollando quanto segue nel riquadro **Event** JSON. Sostituisci la firma del webhook con il valore calcolato nel passaggio precedente.

   ```
   {
     "headers": {
       "Content-Type": "application/json",
       "x-webhook-signature": "2d672e7a0423fab740fbc040e801d1241f2df32d2ffd8989617a599486553e2a"
     },
     "body": "{\"type\": \"payment.success\", \"orderId\": \"1234\", \"amount\": \"99.99\"}"
   }
   ```

1. Scegli **Save** (Salva).

1. Scegli **Richiama **.

   Verrà visualizzato un output simile al seguente:

------
#### [ Python ]

   ```
   Status: Succeeded
   Test Event Name: myEvent
   
   Response:
   {
     "statusCode": 200,
     "body": "{\"received\": true}"
   }
   
   Function Logs:
   START RequestId: 50cc0788-d70e-453a-9a22-ceaa210e8ac6 Version: $LATEST
   Processing successful payment for order 1234
   END RequestId: 50cc0788-d70e-453a-9a22-ceaa210e8ac6
   REPORT RequestId: 50cc0788-d70e-453a-9a22-ceaa210e8ac6	Duration: 1.55 ms	Billed Duration: 2 ms	Memory Size: 128 MB	Max Memory Used: 36 MB	Init Duration: 136.32 ms
   ```

------
#### [ Node.js ]

   ```
   Status: Succeeded
   Test Event Name: myEvent
   
   Response:
   {
     "statusCode": 200,
     "body": "{\"received\":true}"
   }
   
   Function Logs:
   START RequestId: e54fe6c7-1df9-4f05-a4c4-0f71cacd64f4 Version: $LATEST
   2025-01-10T18:05:42.062Z	e54fe6c7-1df9-4f05-a4c4-0f71cacd64f4	INFO	Processing successful payment for order 1234
   END RequestId: e54fe6c7-1df9-4f05-a4c4-0f71cacd64f4
   REPORT RequestId: e54fe6c7-1df9-4f05-a4c4-0f71cacd64f4	Duration: 60.10 ms	Billed Duration: 61 ms	Memory Size: 128 MB	Max Memory Used: 72 MB	Init Duration: 174.46 ms
   
   Request ID: e54fe6c7-1df9-4f05-a4c4-0f71cacd64f4
   ```

------

## Prova la funzione utilizzando una richiesta HTTP
<a name="urls-webhook-tutorial-test-curl"></a>

Usa lo strumento da riga di comando curl per testare il tuo endpoint webhook.

**Prova la funzione usando le richieste HTTP**

1. In un terminale o in un programma shell, esegui il seguente comando curl. Sostituisci l'URL con il valore dell'endpoint URL della tua funzione e sostituisci la firma del webhook con la firma calcolata utilizzando la tua chiave segreta.

   ```
   curl -X POST https://ryqgmbx5xjzxahif6frvzikpre0bpvpf.lambda-url.us-west-2.on.aws/ \
   -H "Content-Type: application/json" \
   -H "x-webhook-signature: d5f52b76ffba65ff60ea73da67bdf1fc5825d4db56b5d3ffa0b64b7cb85ef48b" \
   -d '{"type": "payment.success", "orderId": "1234", "amount": "99.99"}'
   ```

   Verrà visualizzato l’output seguente:

   ```
   {"received": true}
   ```

1. Esamina CloudWatch i log della tua funzione per confermare che abbia analizzato correttamente il payload effettuando le seguenti operazioni:

   1. Apri la pagina del [gruppo Logs](https://console.aws.amazon.com/cloudwatch/home#logsV2:log-groups) nella CloudWatch console Amazon.

   1. Seleziona il gruppo di log della tua funzione (`/aws/lambda/myLambdaWebhook`).

   1. Seleziona il flusso di log più recente.

      Dovresti vedere un output simile al seguente nei log della tua funzione:

------
#### [ Python ]

      ```
      Processing successful payment for order 1234
      ```

------
#### [ Node.js ]

      ```
      2025-01-10T18:05:42.062Z e54fe6c7-1df9-4f05-a4c4-0f71cacd64f4 INFO Processing successful payment for order 1234
      ```

------

1. Verifica che il codice rilevi una firma non valida eseguendo il seguente comando curl. Sostituisci l'URL con il tuo endpoint URL della funzione.

   ```
   curl -X POST https://ryqgmbx5xjzxahif6frvzikpre0bpvpf.lambda-url.us-west-2.on.aws/ \
   -H "Content-Type: application/json" \
   -H "x-webhook-signature: abcdefg" \
   -d '{"type": "payment.success", "orderId": "1234", "amount": "99.99"}'
   ```

   Verrà visualizzato l’output seguente:

   ```
   {"error": "Invalid signature"}
   ```

## Pulizia delle risorse
<a name="urls-webhook-tutorial-cleanup"></a>

Ora è possibile eliminare le risorse create per questo tutorial, a meno che non si voglia conservarle. Eliminando AWS le risorse che non utilizzi più, eviti addebiti inutili a tuo carico. Account AWS

**Per eliminare la funzione Lambda**

1. Aprire la pagina [Functions (Funzioni)](https://console.aws.amazon.com/lambda/home#/functions) della console Lambda.

1. Selezionare la funzione creata.

1. Scegliere **Operazioni**, **Elimina**.

1. Inserisci **confirm** nel campo di immissione del testo, quindi scegli **Elimina**.

Quando hai creato la funzione Lambda nella console, Lambda ha anche creato un [ruolo di esecuzione](lambda-intro-execution-role.md) per la tua funzione.

**Come eliminare il ruolo di esecuzione**

1. Aprire la pagina [Ruoli](https://console.aws.amazon.com/iam/home#/roles) della console IAM.

1. Seleziona il ruolo di esecuzione creato da Lambda. Il ruolo ha il formato `myLambdaWebhook-role-<random string>` del nome.

1. Scegliere **Elimina**.

1. Inserisci il nome del ruolo nel campo di immissione testo e seleziona **Elimina**.