> This is a page from the ElevenLabs documentation. For an index of the documentation, fetch https://elevenlabs.io/docs/llms.txt.

# Voximplant

> **Warning**
>
> L'integrazione con Voximplant è disponibile in misura limitata e viene abilitata per workspace. Contatta il tuo
> referente ElevenLabs prima di instradare il traffico dei clienti.

## Panoramica

L'integrazione con Voximplant collega direttamente una chiamata in uno scenario VoxEngine a un agente in
ElevenAgents tramite WebSocket, usando Voximplant Media Streams. Voximplant gestisce la telefonia:
effettua o risponde alla chiamata e decide cosa succede dopo. ElevenAgents gestisce la
conversazione. Non sono richiesti trunk SIP né middleware.

Le chiamate in entrata e in uscita funzionano allo stesso modo: una volta connessa la chiamata, lo scenario apre un
WebSocket per chiamata verso ElevenLabs. Al termine della conversazione, ElevenLabs invia allo scenario un singolo
evento decisionale che indica se trasferire il chiamante a un operatore, riagganciare o considerare la chiamata come un
timeout.

## Come funziona l'integrazione

1. Il tuo scenario VoxEngine risponde a una chiamata in entrata o ne effettua una in uscita.
2. Lo scenario apre un WebSocket verso l'endpoint ElevenLabs del tuo agente, autenticandosi con una
   chiave API ElevenLabs come bearer token.
3. Lo scenario avvia il flusso multimediale con `call.sendMediaTo()`, passando eventuali `customParameters`.
   ElevenLabs trasforma ogni parametro in una variabile dinamica e risponde con il proprio `start`.
4. Voximplant ed ElevenLabs scambiano audio PCM lineare a 16 bit e 8 kHz in messaggi `media`.
5. Al termine della conversazione, ElevenLabs invia il resto dell'ultima frase dell'agente, un
   evento personalizzato `elevenlabs-decision` e un messaggio `stop`. Lo scenario chiude quindi il WebSocket
   e agisce in base alla decisione.

## Requisiti

Prima di iniziare, assicurati di avere:

1. Un account Voximplant con un'applicazione, un numero di telefono o la possibilità di effettuare chiamate in uscita e l'autorizzazione a
   modificare gli scenari.
2. Un workspace ElevenLabs con l'integrazione Voximplant abilitata.
3. Un agente ElevenLabs e una chiave API dedicata.

## Configura ElevenLabs

#### Crea o seleziona un agente

Crea l'agente in ElevenAgents. Imposta un primo messaggio se deve parlare non appena la chiamata
si connette. I formati audio sono impostati dall'integrazione, quindi i formati configurati dell'agente non vengono usati
per le chiamate Voximplant.

#### Abilita Termina chiamata

In **Agente → Strumenti → Strumenti di sistema**, abilita **Termina chiamata** affinché l'agente possa concludere la conversazione.
Il motivo fornito dall'agente quando termina la chiamata viene inviato al tuo scenario insieme alla decisione.

#### Aggiungi una regola di trasferimento Voximplant (facoltativo)

Per consentire all'agente di trasferire il chiamante a un operatore, assegnagli lo strumento di sistema **Trasferisci a numero** con una
regola di trasferimento la cui configurazione del provider sia `voximplant`. La regola non ha destinazione: la
conversazione termina con una decisione `transfer-to-agent` e il tuo scenario instrada il chiamante. Le regole di trasferimento
vengono configurate tramite l'API. Aggiungi lo strumento con un `PATCH` sull'agente:

```bash
curl -X PATCH "https://api.elevenlabs.io/v1/convai/agents/agent_7101k5zvyjhmfg983brhmhkd98n6" \
  -H "xi-api-key: $ELEVENLABS_API_KEY" -H "Content-Type: application/json" \
  -d '{
    "conversation_config": {"agent": {"prompt": {"built_in_tools": {
      "end_call": {"type": "system", "name": "end_call", "description": "",
                   "params": {"system_tool_type": "end_call"}},
      "transfer_to_number": {
        "type": "system", "name": "transfer_to_number", "description": "",
        "params": {
          "system_tool_type": "transfer_to_number",
          "transfers": [],
          "transfer_rules": [{
            "condition": "the caller asks to speak with a human",
            "provider_configs": [
              {"type": "voximplant", "config": {"type": "voximplant_handoff"}}
            ]
          }]
        }
      }
    }}}}
  }'
```

Invia l'intero oggetto `built_in_tools` dell'agente, inclusi gli strumenti che possiede già, come `end_call`.
L'opzione che l'agente restituisce è il token fisso `voximplant`, quindi è sufficiente una regola Voximplant per strumento.
I numeri di telefono e gli URI SIP configurati per altri provider non vengono offerti nelle chiamate Voximplant.

> **Note**
>
> Le regole di trasferimento sono un'impostazione gestita tramite API. Configura e aggiorna lo strumento **Trasferisci a numero** di
> un agente che le usa tramite l'API, come sopra; l'editor degli strumenti nella dashboard funziona con l'elenco di trasferimento
> per numero.

#### Crea una chiave API dedicata

Crea una chiave API nello stesso workspace dell'agente e limitane l'ambito a ElevenAgents. Per accettare
connessioni soltanto da Voximplant, limita gli indirizzi IP consentiti della chiave ai server multimediali Voximplant,
elencati da Voximplant all'indirizzo
`https://api.voximplant.com/getMediaResources?with_mediaservers`.

#### Annota l'URL WebSocket

Lo scenario si connette a un URL che contiene l'ID del tuo agente:

| Ambiente           | URL                                                                                                               |
| ------------------ | ----------------------------------------------------------------------------------------------------------------- |
| Predefinito        | `wss://api.elevenlabs.io/v1/convai/conversation/voximplant/agent_7101k5zvyjhmfg983brhmhkd98n6`                    |
| Residenza dei dati | `wss://api.<region>.residency.elevenlabs.io/v1/convai/conversation/voximplant/agent_7101k5zvyjhmfg983brhmhkd98n6` |

Per fissare un branch dell'agente, aggiungi `?branch_id=<branch_id>`.

> **Info**
>
> Se il tuo account ElevenLabs si trova in un ambiente di residenza isolato, sostituisci `<region>` con il codice della tua
> regione. Consulta la pagina sulla [residenza dei dati](/docs/it/overview/administration/data-residency) per le regioni
> disponibili.

## Configura Voximplant

#### Crea un'applicazione

Nel [pannello di controllo Voximplant](https://manage.voximplant.com/applications), apri **Applications**
e fai clic su **Create application**. Assegnale un nome, ad esempio `elevenlabs-agent`, quindi fai clic su
**Create**.

![Voximplant: crea applicazione](/docs/_fern-files/_img/29af341fa0a32eaaab444ade8305208121487413c5868597386a973b14fe4fe7.webp)

#### Salva la chiave API come segreto

Nell'applicazione, apri **Secrets** e fai clic su **Add secret**. Assegna il nome `ELEVENLABS_API_KEY`, incolla
in **Value** la chiave API creata per il workspace dell'agente e fai clic su **Add secret**. Lo
scenario la legge con `VoxEngine.getSecretValue()`, quindi la chiave non appare mai nel codice dello scenario.

![Voximplant: aggiungi segreto](/docs/_fern-files/_img/ecf8be823bbc15b263e3f4838684a78de3a3594704be0055b443d15ab93e1485.webp)

#### Crea lo scenario

Apri **Scenarios**, fai clic su **Create scenario**, chiamalo `elevenlabs_agent`, incolla il codice qui sotto,
sostituisci l'ID dell'agente in `ELEVENLABS_URL` e fai clic su **Save**. Risponde a una chiamata in entrata, la trasmette
all'agente e agisce in base alla decisione al termine della conversazione. Per una chiamata in uscita, apri
il WebSocket nel gestore `CallEvents.Connected` della chiamata effettuata.

```javascript maxLines=0
const ELEVENLABS_URL =
  "wss://api.elevenlabs.io/v1/convai/conversation/voximplant/agent_7101k5zvyjhmfg983brhmhkd98n6";

VoxEngine.addEventListener(AppEvents.CallAlerting, ({ call }) => {
  call.answer();
  let decision = null;

  const ws = VoxEngine.createWebSocket(ELEVENLABS_URL, {
    headers: [
      {
        name: "Authorization",
        value: `Bearer ${VoxEngine.getSecretValue("ELEVENLABS_API_KEY")}`,
      },
    ],
  });

  ws.addEventListener(WebSocketEvents.OPEN, () => {
    call.sendMediaTo(ws, {
      encoding: WebSocketAudioEncoding.PCM16_8KHZ,
      customParameters: { customer_name: "Ana", task_id: "task-7" },
    });
    ws.sendMediaTo(call);
  });

  ws.addEventListener(WebSocketEvents.MESSAGE, ({ text }) => {
    const message = JSON.parse(text);
    if (message.customEvent === "elevenlabs-decision") {
      decision = message.payload;
      Logger.write(`ElevenLabs decision: ${JSON.stringify(decision)}`);
    }
  });

  ws.addEventListener(WebSocketEvents.CLOSE, (e) => {
    Logger.write(`ElevenLabs socket closed: code=${e.code} reason=${e.reason}`);
    if (decision?.action === "transfer-to-agent") {
      // Route the caller to a human here, for example with VoxEngine.callPSTN().
      call.say("Connecting you to an agent.", { language: VoiceList.Amazon.en_US_Joanna });
      call.addEventListener(CallEvents.PlaybackFinished, () => call.hangup());
      return;
    }
    call.hangup();
  });

  call.addEventListener(CallEvents.Disconnected, () => {
    ws.close();
    VoxEngine.terminate();
  });
});
```

![Voximplant: lo scenario nell'editor](/docs/_fern-files/_img/d2e26165f57cae40fc01e8de28052fef09b2f98bd90c0e1a8779423715f61e2e.webp)

#### Instrada le chiamate allo scenario

Apri **Routing**, fai clic su **Create rule**, assegnale un nome e assegna lo scenario `elevenlabs_agent`.
Il pattern predefinito `.*` invia ogni chiamata all'applicazione tramite lo scenario;
limitalo a un numero di telefono se l'applicazione gestisce anche altre chiamate. Per instradare un numero di telefono,
collegalo all'applicazione in **Numbers**.

![Voximplant: crea regola](/docs/_fern-files/_img/bc6830b7dcd66dc0b59595456b1197bdcbb9174f15778da7ba9655ba4b93936e.webp)

#### Effettua una chiamata di prova

Puoi chiamare l'applicazione dal browser senza un numero di telefono:

1. Apri **Users**, fai clic su **Create user** e crea un utente con una password.

   ![Voximplant: nuovo utente](/docs/_fern-files/_img/4754c9234588fd0caa336e1168e207b265557dc4e6a12b1cf8bced1275b8bae6.webp)

2. In **Routing**, fai clic su **Test tools**, poi su **Softphone**. Accedi come quell'utente, consenti
   l'accesso al microfono, inserisci una destinazione qualsiasi e chiama. L'agente risponde con il suo primo messaggio.

3. Al termine della chiamata, apri **Call history**. Ogni chiamata elenca una sessione WebSocket accanto alla chiamata
   stessa. Fai clic su **View log** per visualizzare la sessione.

   ![Voximplant: cronologia chiamate](/docs/_fern-files/_img/4e2416ad3587bb320300173cf679f7c5d7a5e545550b0a647062a79866dac40c.webp)

   Il log mostra la decisione inviata da ElevenLabs, la chiusura del WebSocket e cosa ha fatto poi lo scenario.
   In questo esempio il chiamante ha chiesto di parlare con una persona, quindi la decisione è `transfer-to-agent`
   con il motivo fornito dall'agente.

   ![Voximplant: log della sessione con l'evento
   elevenlabs-decision](/docs/_fern-files/_img/f8b4602fa02cfd3c417557377aaa5dd66e2e88a67e7adf4cb037ccae1840f45c.webp)

> **Warning**
>
> Agisci in base all'evento `elevenlabs-decision`, non a `MEDIA_ENDED`. Voximplant attiva `MEDIA_ENDED` dopo
> circa un secondo senza audio da ElevenLabs, cosa che può accadere nel mezzo di una conversazione.

## Variabili dinamiche

Ogni chiave in `customParameters` diventa una variabile dinamica con lo stesso nome. I valori che non sono
stringhe vengono convertiti in testo, ad esempio `true` diventa `"true"`. `customParameters` può essere un
oggetto o una stringa codificata in JSON. Le chiavi che iniziano con `system__` o `integration__` sono riservate e
vengono ignorate.

## Eventi decisionali

Al termine della conversazione, ElevenLabs invia esattamente una decisione prima del messaggio `stop`:

```json
{ "customEvent": "elevenlabs-decision", "payload": { "action": "terminate", "reason": "under_18" } }
```

| `action`            | Quando viene inviata                                                                                                                                                                                                      | `reason`                                                             |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| `transfer-to-agent` | L'agente ha chiamato **Trasferisci a numero** con una regola di trasferimento Voximplant.                                                                                                                                 | Il motivo fornito dall'agente per il trasferimento.                  |
| `timeout`           | La conversazione è andata in timeout per silenzio o dopo l'ultimo messaggio dell'agente, oppure l'agente ha terminato la chiamata dopo 15 secondi di silenzio del chiamante, escludendo il tempo in cui l'agente parlava. | Il messaggio di timeout o il motivo fornito dall'agente.             |
| `terminate`         | L'agente ha terminato la chiamata con **Termina chiamata**, oppure la conversazione è terminata normalmente.                                                                                                              | Il motivo fornito dall'agente con **Termina chiamata**, se presente. |
| `unexpected`        | La conversazione è terminata a causa di un errore.                                                                                                                                                                        | Una descrizione dell'errore.                                         |

Se lo scenario invia prima `stop` o chiude il WebSocket, ad esempio perché il chiamante ha riagganciato,
ElevenLabs non invia alcuna decisione.

## Audio

Voximplant ed ElevenLabs scambiano PCM lineare mono a 16 bit e 8 kHz in entrambe le direzioni. ElevenLabs
riproduce l'audio dell'agente a un ritmo vicino al tempo reale, quindi quando il chiamante interrompe l'agente, vengono ancora riprodotti al massimo
circa 0,4 secondi della risposta interrotta.

## Errori di autenticazione

ElevenLabs chiude il WebSocket con codice `1008` e motivo `bad auth token` quando l'header
`Authorization` è assente o non valido, la chiave API non è valida o non è consentita dall'indirizzo IP di
connessione, la chiave appartiene a un altro workspace oppure l'utente della chiave non può accedere a un
agente con l'autenticazione abilitata.

## Limitazioni e funzionalità non supportate

* Gli strumenti client e lo strumento di sistema **Riproduci tono tastiera** non sono supportati. **Trasferisci a
  numero** funziona soltanto tramite una regola di trasferimento Voximplant; lo scenario decide dove
  inviare il chiamante.
* Gli override di configurazione, come un primo messaggio diverso, non possono essere passati dallo scenario;
  sono possibili soltanto le variabili dinamiche.
* I risultati della raccolta dati non vengono inviati allo scenario. Usa il
  [webhook post-chiamata](/docs/it/eleven-agents/workflows/post-call-webhooks) per ottenerli.